在 SwiftUI 中禁用 macOS 对焦环

Ala*_*lan 6 macos cocoa swiftui

是否可以TextField在 Mac 的 swiftUI 中禁用围绕 a 的聚焦环?

小智 6

我也有这个问题,经过几个小时的摆弄,似乎答案是否定的。但是,可以包装 NSTextField 并摆脱聚焦环。

以下代码已在最新版本中进行了测试。

struct CustomTextField: NSViewRepresentable {
    @Binding var text: String

    init(text: Binding<String>) {
        _text = text
    }

    func makeNSView(context: Context) -> NSTextField {
        let textField = NSTextField(string: text)
        textField.delegate = context.coordinator
        textField.isBordered = false
        textField.backgroundColor = nil
        textField.focusRingType = .none
        return textField
    }

    func updateNSView(_ nsView: NSTextField, context: Context) {
        nsView.stringValue = text
    }

    func makeCoordinator() -> Coordinator {
        Coordinator { self.text = $0 }
    }

    final class Coordinator: NSObject, NSTextFieldDelegate {
        var setter: (String) -> Void

        init(_ setter: @escaping (String) -> Void) {
            self.setter = setter
        }

        func controlTextDidChange(_ obj: Notification) {
            if let textField = obj.object as? NSTextField {
                setter(textField.stringValue)
            }
        }

    }

}
Run Code Online (Sandbox Code Playgroud)


The*_*eil 5

正如Asperi在此处对类似问题的回答中所述,不可能(在 iOS 17 / macOS 14 之前)使用 SwiftUI 关闭特定字段的对焦环;但是,以下解决方法将禁用NSTextField应用程序中所有实例的对焦环:

extension NSTextField {
    open override var focusRingType: NSFocusRingType {
        get { .none }
        set { }
    }
}
Run Code Online (Sandbox Code Playgroud)

并不理想,但它确实提供了一种不需要在 SwiftUI 之外走得太远的选项。