RxSwift中的textFiled的使用
let textFiled = UITextField()
textFiled.frame = CGRect(origin: CGPoint(x: 100, y: 100), size: CGSize(width: 300, height: 200))
textFiled.backgroundColor = UIColor.red
self.view.addSubview(textFiled)
let _ = textFiled.rx.text.subscribe(onNext: { (content) in
if let tmpString = content{
print("收到消息 -------" + tmpString)
}
}, onError: { (error) in
print("\(error)")
}, onCompleted: {
print("completed ...")
}) {
print("disposed...")
}
在我们的程序启动后,我们就收到一次订阅,这是为什么,在哪里触发一次消息发送,先对这个时间进行探究,从.text进入RxSwift中的UItextFieid+RxSwift.swift我们看到了对应的代码实现,如下
extension Reactive where Base: UITextField {
/// Reactive wrapper for `text` property.
public var text: ControlProperty<String?> {
return value
}
/// Reactive wrapper for `text` property.
public var value: ControlProperty<String?> {
return base.rx.controlPropertyWithDefaultEvents(
getter: { textField in
textField.text
},
setter: { textField, value in
// This check is important because setting text value always clears control state
// including marked text selection which is imporant for proper input
// when IME input method is used.
if textField.text != value {
textField.text = value
}
}
)
}
// 省略其他代码
// ....
}
代码分析
我们使用的text属性是继承自ControlProperty结构体的属性,其返回的数据是value,value的getter方法textfield的rx属性的controlPropertyWithDefaultEvents方法,在这个方法中有对应的value值的返回,
代码片1
// 代码片1
internal func controlPropertyWithDefaultEvents<T>(
editingEvents: UIControlEvents = [.allEditingEvents, .valueChanged],
getter: @escaping (Base) -> T,
setter: @escaping (Base, T) -> Void
) -> ControlProperty<T> {
return controlProperty(
editingEvents: editingEvents,
getter: getter,
setter: setter
)
}
// 代码片2
public func controlProperty<T>(
editingEvents: UIControlEvents,
getter: @escaping (Base) -> T,
setter: @escaping (Base, T) -> Void
) -> ControlProperty<T> {
let source: Observable<T> = Observable.create { [weak weakControl = base] observer in
guard let control = weakControl else {
observer.on(.completed)
return Disposables.create()
}
observer.on(.next(getter(control)))
let controlTarget = ControlTarget(control: control, controlEvents: editingEvents) { _ in
if let control = weakControl {
observer.on(.next(getter(control)))
}
}
return Disposables.create(with: controlTarget.dispose)
}
.takeUntil(deallocated)
let bindingObserver = Binder(base, binding: setter)
return ControlProperty<T>(values: source, valueSink: bindingObserver)
}
结合这两段代码,代码片1中我们规定了两种事件类型,分别是.allEditingEvents和.valueChanged;
- 在代码片2中创建序列的时,我们可以看到
observer.on(.next(getter(control)))这种类型的event它是,订阅了我们UI空间的初始化event; let controlTarget = ControlTarget(control: control, controlEvents: editingEvents) {...}这段代码的实现是尾随的逃逸闭包,下面我来看内部的实现代码分析 这里边,其实就是将,init(control: Control, controlEvents: UIControlEvents, callback: @escaping Callback) { MainScheduler.ensureRunningOnMainThread() self.control = control self.controlEvents = controlEvents self.callback = callback super.init() control.addTarget(self, action: selector, for: controlEvents) let method = self.method(for: selector) if method == nil { rxFatalError("Can't find method") } }UItextField的event类型的触发方法内部绑定到了textField上,这个触发方法就是eventHandler,在其中就会调用callBack,通过这样的方式就订阅到了textfield的所有的触发事件 然后再通过let bindingObserver = Binder(base, binding: setter)将textfield的赋值event将其定义成绑定观察者,最后在最外层subscribe订阅触发对应的event的事件处理
以上代码多有,不正确之处和写的不详细的地方,欢迎大家扶正和批评,谢谢