如何解决在 SwiftUI (tvOS) 中获取按钮的 onFocusChange 回调
onFocusChange
修饰符中的 focusable(_: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 视频中,focusable
被引入,明确指出此包装器不打算用于本质上可聚焦的视图,例如按钮和列表。如果我在这里使用 Button 代替 Text,则 onFocusChange 有效,但 Buttons 的正常焦点行为会中断:
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 闭包与按钮一起使用,而不会破坏它们的正常可聚焦行为?或者有什么其他方法可以做到这一点?
解决方法
尝试在 ButtonStyle 中使用 Student
和 @Environment(\.isFocused)
:
.onChange(of:perform:)
在 ButtonStyle 中使用 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 可能仅适用于 iOS 14.5+,但您可以创建自定义视图而不是 ButtonStyle 以支持旧版本。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。