SwiftUI:使用“View.defaultFocus()”将按钮标记为默认值在 macOS 上没有任何作用

问题描述 投票:0回答:1

我有一个简单的 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)
    }
}

我错过了什么?为什么不起作用?

macos swiftui focus
1个回答
0
投票

经过更多实验,我找到了一种让它发挥作用的方法。由于某些奇怪的原因,

.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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.