我有一个简单的 macOS 应用程序,我想告诉焦点子系统默认情况下特定按钮应该获得焦点:
struct ContentView: View {
@FocusState private var focusedElement: FocusedElement?
@Namespace private var namespace
var body: some View {
VStack {
self.makeButton(element: .button1)
self.makeButton(element: .button2)
.prefersDefaultFocus(in: self.namespace) // doesn't have any effect
}
.defaultFocus(self.$focusedElement, .button2) // doesn't have any effect
.focusScope(self.namespace)
.onChange(of: self.focusedElement) { newValue in
print("focusedElement:", newValue.debugDescription )
}
}
}
private extension ContentView {
enum FocusedElement: Hashable, Identifiable {
case button2
case button1
var id: FocusedElement { self }
}
@ViewBuilder
func makeButton(element: FocusedElement) -> some View {
Button(action: { }, label: {
Text(String(describing: element))
})
.id(element)
.focused(self.$focusedElement, equals: element)
}
}
我错过了什么?为什么不起作用?
经过更多实验,我找到了一种让它发挥作用的方法。由于某些奇怪的原因,
.buttonStyle
视图修饰符似乎对@FocusState如何工作和不工作有很大的影响。
我注意到以下行为:
1。不提供
.buttonStyle
或除 .buttonStyle(.plain)
以外的任何内容
2。自定义
ButtonStyle
或 .buttonStyle(.plain) is provided
.defaultFocus()
视图修改器似乎按预期工作完整代码:
struct ContentView: View {
// Focus management
@FocusState private var focusedElement: FocusedElement?
@Namespace private var namespace
// MARK: - View
var body: some View {
VStack {
self.makeButton(element: .button1)
self.makeButton(element: .button2)
.prefersDefaultFocus(in: self.namespace) // Doesn't have any effect even with `buttonStyle(.plain)`
}
.buttonStyle(MyButtonStyle()) // Using `.plain` or `MyButtonStyle()` makes the .defaultFocus work as expected
.defaultFocus(self.$focusedElement, .button2) // Does seem to work when `buttonStyle(.plain)` or `.buttonStyle(MyButtonStyle())` is specified
.focusScope(self.namespace)
.onChange(of: self.focusedElement) { newValue in
print("focusedElement:", newValue.debugDescription )
}
}
}
struct MyButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding(5.0)
.background(.quaternary, in: Capsule())
.opacity(configuration.isPressed ? 0.5 : 1)
}
}
3.提供自定义
PrimitiveButtonStyle
`
.focusable()
视图修饰符:struct MyButtonStyle: PrimitiveButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding(5.0)
.background(.quaternary, in: Capsule())
.focusable() // PrimitiveButtonStyle doesn't make focusable buttons by default
}
}