swift - 在 SwiftUI 中处理 UITextView 的 UIResponder

标签 swift swiftui uiresponder

我正在尝试处理 SwiftUI 中 UITextView 现有子类的 UIResponder。我已经能够使用协调器模式来处理 UITextViewDelegate,但我在使用 UIResponder 时遇到了问题。

在过去(使用 UIKit),我会做的是使用 NotificationCenterUIViewController< 的子类中添加 UIResponder.keyboardWillShowNotification 的观察者.

在 SwiftUI 中,我不知道该把它放在哪里。我做了一件简单的事情,就是在 makeUIView 中重用 Coordinator 类,如下所示:

    let nc = NotificationCenter.default
    nc.addObserver(context.coordinator, selector: #selector(Coordinator.keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: editorTextView)

但是 keyboardWillShow 方法永远不会被调用。我这样做错了吗?

最佳答案

我建议使用组合发布器,这样您就不需要弄乱选择器,但这应该可以以任何方式工作。本例中观察者/选择器模式被注释掉,但如果取消注释,观察者和发布者都应该在键盘出现时做出响应。

    import Combine
    import SwiftUI
    import UIKit

    struct MyTextView: UIViewRepresentable {
    // Pass in the binding to the string from the SwiftUI view
    var text: Binding<String>

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

    func makeUIView(context: Context) -> UITextField {
        let tf = UITextField()
        tf.delegate = context.coordinator
        tf.text = context.coordinator.text.wrappedValue // Access the wrapped value in the binding
        return tf
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        //
    }

    func makeCoordinator() -> MyTextViewDelegate {
        let delegate = MyTextViewDelegate(text: text)
        return delegate
    }

    class MyTextViewDelegate: NSObject, UITextFieldDelegate {
//      let nc = NotificationCenter.default
        var text: Binding<String>

        // You can use a Combine Publisher rather than dealing with selectors
        var subscriber: AnyCancellable?

        init(text: Binding<String>) {
            self.text = text
            super.init()
            subscriber = NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)
                .sink() { [weak self] note in
                    print(self?.text.wrappedValue ?? "nil")
                    print("Publisher called -> " + note.description)
            }
//            nc.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        }


//        @objc func keyboardWillShow(notification: Notification) {
//            print("Selector called -> " + notification.description)
//        }

        // Value should update in SwiftUI when return key is pressed to show that the data flows
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            self.text.wrappedValue = textField.text ?? ""
            print(textField.text!)
            return true
        }
    }
}

关于swift - 在 SwiftUI 中处理 UITextView 的 UIResponder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61201617/

相关文章:

ios - 使用字典值填充 tableView 内的 collectionView 标签

swift - 在 2 个页面之间传递状态 SwiftUI

swift - SwiftUI 应用程序的 NavigationView 中的 onAppear 和 onDisappear 是否按预期运行?

ios - UITableViewCell 中的 UITextField 和所选单元格键盘上的变为FirstResponder 显示/隐藏故障

ios - 自定义编辑菜单中 UIMenuItems 的顺序

ios - 重启滑行序列

ios - 如何在没有 Storyboard的情况下调整 iPad 和 iPhone 4S 的 View 大小?

swift - CIFilter 中的图像不会显示

python - SwiftUI - 用 Python 和模块库打包

swift - 'resignFirstResponder()' 返回 true 并且文本字段失去焦点但键盘不会关闭