【问题标题】:Multiple UITextFields and textDidChangeNotification notification多个 UITextFields 和 textDidChangeNotification 通知
【发布时间】:2019-06-23 20:21:37
【问题描述】:

我最近在玩 Combine 框架,想知道是否可以创建一些智能扩展来作为 Publisher 获取文本更改。

假设我有两个 UITextField:

firstTextField.textPub.sink {
    self.viewModel.first = $0
}

secondTextField.textPub.sink {
    self.viewModel.second = $0
}

第一个和第二个变量只是`@Published var first/second: String = ""

extension UITextField {
    var textPub: AnyPublisher<String, Never> {
        return NotificationCenter.default
            .publisher(for: UITextField.textDidChangeNotification)
            .map {
                guard let textField = $0.object as? UITextField else { return "" }
                return textField.text ?? ""
            }
            .eraseToAnyPublisher()
    }
}

这不起作用,因为我使用的是 NotificationCenter 的共享实例,所以当我对任何 textFields 进行任何更改时,它会将新值传播到 sink 闭包。你认为有什么方法可以实现类似于 RxSwift 中的rx.text 的东西吗?我正在考虑使用带有闭包的addTarget,但它需要使用来自 Objective-C 的关联对象。

【问题讨论】:

    标签: swift uikit combine


    【解决方案1】:

    我想通了。我们可以使用 NotificationCenter 传递对象,然后过滤所有与我们的实例不匹配的实例。它似乎按我的预期工作:

    extension UITextField {
        var textPublisher: AnyPublisher<String, Never> {
            NotificationCenter.default
                .publisher(for: UITextField.textDidChangeNotification, object: self)
                .compactMap { $0.object as? UITextField }
                .map { $0.text ?? "" }
                .eraseToAnyPublisher()
        }
    }
    

    【讨论】:

      【解决方案2】:

      我建议您将订阅者添加到视图模式,并将它们连接到视图控制器上下文中的文本字段发布者。

      NotificationCenter 对于在应用范围内调度事件很有用;连接完全由 View Controller 拥有的项目时,无需使用它。但是,一旦您更新了视图模式,将“视图模式发生变化”事件发布到 NotificationCenter 可能是有意义的。

      【讨论】:

      • 是的,但它需要为每个文本字段添加目标并将文本分配给@Published 属性。
      猜你喜欢
      • 2017-01-09
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-04
      相关资源
      最近更新 更多