SwiftUI: уберите выделенную границу 'Focus Ring' из macOS TextField - PullRequest
1 голос
/ 19 января 2020

Я использовал приведенный ниже код для создания пользовательской панели поиска в SwiftUI. Он отлично работает на iOS / Catalyst:

SearchTextView on iOS / Catalyst

... но при естественном запуске в macOS стилизация границ фокуса 'ring ring' выделяется ( когда пользователь выбирает текстовое поле) скорее разрушает эффект:

SearchTextView on Native macOS

Использование .textFieldStyle(PlainTextFieldStyle()) удаляет большую часть стиля по умолчанию из базового поля ( я считаю, что это NSTextField), но не кольцо фокусировки.

Есть ли способ удалить это тоже? Я попытался создать пользовательский TextFieldStyle и применить его, но не смог найти никакого модификатора для стилизации этой границы.

public struct SearchTextView: View {

    @Binding var searchText: String

    #if !os(macOS)
    private var backgroundColor = Color(UIColor.secondarySystemBackground)
    #else
    private var backgroundColor = Color(NSColor.controlBackgroundColor)
    #endif

    public var body: some View {

        HStack {

            Spacer()

            #if !os(macOS)
            Image(systemName: "magnifyingglass")
            #else
            Image("icons.general.magnifyingGlass")
            #endif

            TextField("Search", text: self.$searchText)
                .textFieldStyle(PlainTextFieldStyle())
                .foregroundColor(.primary)
                .padding(8)

            Spacer()
        }
        .foregroundColor(.secondary)
        .background(backgroundColor)
        .cornerRadius(12)
        .padding()
    }

    public init(searchText: Binding<String>) {
        self._searchText = searchText
    }
}

1 Ответ

2 голосов
/ 19 февраля 2020

Как указано в ответе Asperi на аналогичный вопрос здесь , невозможно (пока) отключить кольцо фокусировки для указанного поля c с помощью SwiftUI; однако следующий обходной путь отключит кольцо фокусировки для всех NSTextField экземпляров в приложении :

extension NSTextField {
    open override var focusRingType: NSFocusRingType {
        get { .none }
        set { }
    }
}

Если вы хотите заменить его на свое собственное кольцо фокусировки в представлении параметр onEditingChanged может помочь вам достичь этого (см. пример ниже); однако, к сожалению, он вызывается в macOS, когда пользователь вводит первую букву, а не когда он впервые щелкает по полю (что не идеально).

Теоретически вы можете использовать закрытие onFocusChange в Вместо этого модификатор focusable, но в настоящее время он не вызывается для этих текстовых полей macOS (по состоянию на macOS 10.15.3).

public struct SearchTextView: View {

    @Binding var searchText: String

    @State private var hasFocus = false

    #if !os(macOS)
    private var backgroundColor = Color(UIColor.secondarySystemBackground)
    #else
    private var backgroundColor = Color(NSColor.controlBackgroundColor)
    #endif

    public var body: some View {

        HStack {

            Spacer()

            #if !os(macOS)
            Image(systemName: "magnifyingglass")
            #else
            Image("icons.general.magnifyingGlass")
            #endif

            TextField("Search", text: self.$searchText, onEditingChanged: { currentlyEditing in
                self.hasFocus = currentlyEditing // If the editing state has changed to be currently edited, update the view's state
            })
                .textFieldStyle(PlainTextFieldStyle())
                .foregroundColor(.primary)
                .padding(8)

            Spacer()
        }
        .foregroundColor(.secondary)
        .background(backgroundColor)
        .cornerRadius(12)
        .border(self.hasFocus ? Color.accentColor : Color.clear, width: self.hasFocus ? 3 : 0)
        .padding()
    }

    public init(searchText: Binding<String>) {
        self._searchText = searchText
    }
}
...