获取SwiftUI(tvOS)中按钮的onFocusChange回调

获取SwiftUI(tvOS)中按钮的onFocusChange回调,swiftui,focus,tvos,focus-engine,Swiftui,Focus,Tvos,Focus Engine,focusable(\u:onFocusChange:)修改器中的onFocusChange闭包允许我在对焦子视图时设置父视图的属性,如下所示: struct ContentView: View { @State var text: String var body: some View { VStack { Text(text) Text("top") .paddi

focusable(\u:onFocusChange:)
修改器中的
onFocusChange
闭包允许我在对焦子视图时设置父视图的属性,如下所示:

struct ContentView: View {
    @State var text: String
    var body: some View {
        VStack {
            Text(text)
            Text("top")
                .padding()
                .focusable(true, onFocusChange: { focused in
                    text = "top focus"
                })
            Text("bottom")
                .padding()
                .focusable(true, onFocusChange: { focused in
                    text = "bottom focus"
                })
        }
        
    }
}
但在2020年的WWDC视频中,引入了可聚焦的,其中明确指出,中的此包装器不适用于按钮和列表等固有的可聚焦视图。如果我在此处使用按钮代替文本,onFocusChange会起作用,但按钮的正常聚焦行为会中断:

struct ContentView: View {
    @State var text: String
    var body: some View {
        VStack {
            Text(text)
            Button("top") {}
                .padding()
                .focusable(true, onFocusChange: { focused in
                    text = "top focus"
                })
            Button("bottom") {}
                .padding()
                .focusable(true, onFocusChange: { focused in
                    text = "bottom focus"
                })
        }
        
    }
}

有没有一般的方法可以使onFocusChange闭包与按钮一起使用,而不会破坏按钮的正常聚焦行为?或者有其他方法来实现这一点吗?

尝试使用
@Environment(\.isFocused)
。在按钮样式中更改(of:perform:)

struct ContentView: View {
    var body: some View {
          Button("top") {
             // button action
          }
          .buttonStyle(MyButtonStyle())
    }
}

struct MyButtonStyle: ButtonStyle {
    @Environment(\.isFocused) var focused: Bool

    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .onChange(of: focused) { newValue in
                // do whatever based on focus
            }
    }
}

IIRC在ButtonStyle中使用
@Environment(\.isFocused)
可能只在iOS 14.5+上工作,但您可以创建自定义视图而不是ButtonStyle来支持旧版本。

这是否回答了您的问题?@Asperi,不幸的是,没有。使用@Environment(\.isFocused)var focused:Bool,我可以声明性地修改视图的显示方式,例如,使用三元条件,但这不提供任何方法来分配值或执行基于代码的焦点更改。请尝试使用.isFocused环境值和.onChange(of:perform:)来执行代码@亚当,谢谢你。onChange(of:perform:)with.isFocused环境值为我提供了所需的回调。如果你有机会,请加上这个作为答案