RxSwift textField问题

1.1、textFiled 最开始来一次

        textFiled.rx.text.subscribe(onNext: { (text) in
            print("输入来了 \(text)")
        })

步骤1、点击text

    /// Reactive wrapper for `text` property.
    public var text: ControlProperty<String?> {
        return value
    }

步骤2、点击value
controlPropertyWithDefaultEvents 方法传入两个闭包

    /// 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
                }
            }
        )
    }

步骤3、点击controlPropertyWithDefaultEvents
controlPropertyWithDefaultEvents 方法有三个参数
第一个参数:默认值[.allEditingEvents, .valueChanged]
第二个参数:传入的getter闭包
第三个参数:传入的setter闭包

    /// This is a separate method to better communicate to public consumers that
    /// an `editingEvent` needs to fire for control property to be updated.
    internal func controlPropertyWithDefaultEvents<T>(
        editingEvents: UIControl.Event = [.allEditingEvents, .valueChanged],
        getter: @escaping (Base) -> T,
        setter: @escaping (Base, T) -> Void
        ) -> ControlProperty<T> {
        return controlProperty(
            editingEvents: editingEvents,
            getter: getter,
            setter: setter
        )
    }

步骤4、点击controlProperty

    /// Creates a `ControlProperty` that is triggered by target/action pattern value updates.
    ///
    /// - parameter controlEvents: Events that trigger value update sequence elements.
    /// - parameter getter: Property value getter.
    /// - parameter setter: Property value setter.
    public func controlProperty<T>(
        editingEvents: UIControl.Event,
        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)
    }

步骤5、点击ControlTarget
init(control: Control, controlEvents: UIControl.Event, callback: @escaping Callback) {} 初始化 ControlTarget
第一个参数:control
第二个参数:editingEvents -> [.allEditingEvents, .valueChanged]
第三个参数:闭包 -> { _ in if let control = weakControl { observer.on(.next(getter(control))) } }
5.1、self.callback = callback 保存闭包
5.2、control.addTarget(self, action: selector, for: controlEvents) 给传入的control添加事件 绑定#selector(ControlTarget.eventHandler(_:))方法
5.3、事件触发是来到eventHandler,执行callback(control) 执行闭包

// This should be only used from `MainScheduler`
final class ControlTarget: RxTarget {
    typealias Callback = (Control) -> Void

    let selector: Selector = #selector(ControlTarget.eventHandler(_:))

    weak var control: Control?
#if os(iOS) || os(tvOS)
    let controlEvents: UIControl.Event
#endif
    var callback: Callback?
    #if os(iOS) || os(tvOS)
    init(control: Control, controlEvents: UIControl.Event, callback: @escaping Callback) {
        MainScheduler.ensureRunningOnMainThread()

        self.control = control
        self.controlEvents = controlEvents
        self.callback = callback

        super.init()
        
        control.addTarget(self, action: selector, for: controlEvents) // 添加事件 绑定eventHandler方法

        let method = self.method(for: selector)
        if method == nil {
            rxFatalError("Can't find method")
        }
    }
    
    @objc func eventHandler(_ sender: Control!) {
        if let callback = self.callback, let control = self.control {
            callback(control)
        }
    }

}
解决方法: skip(1)
        textFiled.rx.text.skip(1).subscribe(onNext: { (text) in
            print("输入来了 \(text)")
        })

1.2、textFiled text赋值,subscribe闭包不走

原因 步骤3中 editingEvents: UIControl.Event = [.allEditingEvents, .valueChanged],所以不走。这里的valueChanged是UISwitch的值改变哦

解决方法: sendActions(for: .allEditingEvents)
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textFiled.text = "Cooci"
        textFiled.sendActions(for: .allEditingEvents)
    }

2.1、textView 最开始来一次

解决方法: skip(1)
        textView.rx.text.skip(1).subscribe(onNext: { (text) in
            print("textView:输入来了 \(text)")
        })

2.2、textView 不存在,text赋值,subscribe闭包不走

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容