当用户点击键盘时,UITextView 发布者不会发布信号

UITextView publisher doesn't publish a signal when a user taps a keyboard

Apple 说:

Combine also provides a built-in publisher for any property that’s compliant with Key-Value Observing.

所以,我在视图控制器视图中有一个 UITextView 实例,当用户点击键盘时它应该通过发布者发出信号但它没有发生。下面是一段代码,解释了我订阅发布者的方式

class MyViewController : UIViewController {

    var t = UITextView(frame: .init(x: 0, y: 0, width: 100, height: 20))


    override func viewDidLoad() {
    super.viewDidLoad()

        t.publisher(for: \UITextView.text)
            .receive(on: RunLoop.main)
            .sink { (str) in
                print(str)
        }

        view.addSubview(t)
    }
}

您没有存储 subscription a.k.a。 AnyCancellable。只需这样做:

class MyViewController : UIViewController {

    var t = UITextView(frame: .init(x: 0, y: 0, width: 100, height: 20))
    var set = Set<AnyCancellable>()

    override func viewDidLoad() {
    super.viewDidLoad()

        t.publisher(for: \UITextView.text)
            .receive(on: RunLoop.main)
            .sink { (str) in
                print(str)
        }.store(in: &set)

        view.addSubview(t)
    }
}

除了确保您存储您的订阅以使其不会被内存管理删除之外,请注意 UIKit 的大部分不符合 KVO 的事实,并且当事情在 KVO 中工作时,它们'它们通常是快乐事故的结果。

这意味着您可能不希望依赖 KVO 来检索用户输入,除非您准备在每个较小的 iOS 修订版的许多不同场景中继续测试其结果。

相反,您可能一直依赖 UITextViewDelegate 方法(例如 textDidChange(UITextView))来获取此类信息 — 至少目前是这样。如果明年这个时候我们没有任何类型的 UIKit 组合绑定选项,我会感到震惊。