Показать / скрыть навигационные элементы, когда клавиатура видна / не видна | SwiftUI - PullRequest
1 голос
/ 24 февраля 2020

Я потратил много времени на изучение и игру с разными кодами, чтобы сделать эту работу, но не могу понять это. Ниже вы увидите два фрагмента кода, один из которых создает элемент кнопки «Готово», а другой проверяет наличие клавиатуры и закрывает ее при нажатии кнопки. Единственная проблема, с которой я столкнулся - я хочу, чтобы кнопка бара отображалась только при наличии клавиатуры. Я хочу, чтобы кнопка панели была скрыта после того, как клавиатура исчезла или даже до того, как она вообще открылась. Как вы делаете это в настоящее время с SwiftUI?

.navigationBarItems(trailing:
            Button(action: {
                if UIApplication.shared.isKeyboardPresented {
                    UIApplication.shared.endEditing()
                }
            }, label: {
                Text("Done")
            })

extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
    /// Checks if view hierarchy of application contains `UIRemoteKeyboardWindow` if it does, keyboard is presented
    var isKeyboardPresented: Bool {
        if let keyboardWindowClass = NSClassFromString("UIRemoteKeyboardWindow"),
            self.windows.contains(where: { $0.isKind(of: keyboardWindowClass) }) {
            return true
        } else {
            return false
        }
    }
}

1 Ответ

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

Как вариант, вы можете определить объект для прослушивания уведомлений клавиатуры:

class KeybordManager: ObservableObject {
    static let shared = KeybordManager()

    @Published var keyboardFrame: CGRect? = nil

    init() {
        let notificationCenter = NotificationCenter.default
        notificationCenter.addObserver(self, selector: #selector(willHide), name: UIResponder.keyboardWillHideNotification, object: nil)
        notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }

    @objc func willHide() {
        self.keyboardFrame = .zero
    }

    @objc func adjustForKeyboard(notification: Notification) {
        guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }

        let keyboardScreenEndFrame = keyboardValue.cgRectValue
        self.keyboardFrame = keyboardScreenEndFrame
    }
}

Затем внутри вашего представления подпишитесь на keyboardFrame обновления и соответственно отобразите и скройте кнопку Done:

public struct ContentView: View {

    @State private var showDoneButton = false
    @State private var text = ""

    public var body: some View {
        NavigationView {
            TextField("Some text", text: $text)
            .navigationBarItems(trailing:
                Group {
                    if self.showDoneButton {
                        Button(action: {
                            UIApplication.shared.endEditing()
                        }, label: {
                            Text("Done")
                        })
                    } else {
                        EmptyView()
                    }
            }

            )
                .onReceive(KeybordManager.shared.$keyboardFrame) { keyboardFrame in
                    if let keyboardFrame = keyboardFrame, keyboardFrame != .zero {
                        self.showDoneButton = true
                    } else {
                        self.showDoneButton = false
                    }
            }
        }
    }
}

extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...