我最近正在使用Combine框架,想知道是否有可能创建一些智能扩展以使发布者更改文本。
假设我有两个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共享实例,因此,当我对任何textField进行任何更改时,它都会将新值传播到两个sink
闭包中。您是否认为有任何方法可以实现类似于RxSwift中可用的rx.text
的功能?我当时正在考虑将addTarget
与闭包一起使用,但这需要使用Objective-C中的关联对象。
答案 0 :(得分:1)
我知道了。我们可以使用NotificationCenter传递对象,然后过滤所有与我们的实例不匹配的实例。它似乎按我预期的那样工作:
extension UITextField {
var textPublisher: AnyPublisher<String, Never> {
NotificationCenter.default
.publisher(for: UITextField.textDidChangeNotification, object: self)
.compactMap { $0.object as? UITextField }
.filter { $0 == self }
.map { $0.text ?? "" }
.eraseToAnyPublisher()
}
}
答案 1 :(得分:0)
我建议您将订阅者添加到视图模式,并在视图控制器的上下文中将其连接为文本字段发布者。
NotificationCenter可用于在整个应用范围内调度事件;连接View Controller完全拥有的项目时,无需使用它。但是,一旦更新了视图模式,就可以将一个“ View Modal Did Change”事件发布到NotificationCenter。