【问题标题】:Show/hide navigationBarItems when keyboard visible/non-visible | SwiftUI当键盘可见/不可见时显示/隐藏 navigationBarItems | SwiftUI
【发布时间】:2020-06-08 12:55:31
【问题描述】:

我花了很多时间研究和使用不同的代码来完成这项工作,但似乎无法弄清楚。下面你会看到两段代码,一段是我创建“完成”栏按钮项,另一段是检查键盘是否存在,并在单击按钮时关闭它。我遇到的一个问题是,我只希望栏按钮在键盘出现时显示。我希望在键盘消失后或者甚至在首先打开键盘之前隐藏条形按钮。你现在如何使用 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
        }
    }
}

【问题讨论】:

    标签: xcode list navigation swiftui


    【解决方案1】:

    作为一个选项,您可以定义一个对象来监听键盘通知:

    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)
        }
    }
    

    【讨论】:

    • 你是救生员。非常感谢您的快速回复并教会了我一些新东西。好好休息一天!
    • 这太棒了,谢谢
    猜你喜欢
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    相关资源
    最近更新 更多