iosrx-swiftrx-cocoa

Why RxCocoa didn't provide subscribe for UILabel's text change?


RxCocoa provide subscribe for UITextField and UITextView text change:

UITextField().rx.text.orEmpty.changed
    .subscribe { text in
        print(text)
    }
    .disposed(by: disposeBag)

UITextView().rx.text.changed.subscribe { t in
    print(t)
}.disposed(by: disposeBag)

But no convenience for UILabel:

UILabel().rx.text.subscribe ...

Why rxcocoa designed for this?


Solution

  • In essence, the text method is a wrapper around the UIControl's addTarget(:action:for:) method. It turns that method into something that is Observable.

    The UILabel type isn't derived from UIControl and so doesn't have an addTarget(:action:for:) method. You can't attach an @IBAction to a UILabel in normal UIKit, so you can't attach an Rx ControlProperty to a UILabel either.

    And just like in UIKit, you don't need to observe changes to a UILabel because the only way it changes is if your code changed it. Just observe the thing that triggered the label to change instead.


    It will help to understand if you look at the code... The text method is just a rename of the value method:

    public var text: ControlProperty<String?> {
        value
    }
    

    and the value method is a ControlProperty that monitors the "default events".

        public var value: ControlProperty<String?> {
            return base.rx.controlPropertyWithDefaultEvents(
    

    Looking at controlPropertyWithDefaultEvents, we can find out what the default events are:

    internal func controlPropertyWithDefaultEvents<T>(
        editingEvents: UIControl.Event = [.allEditingEvents, .valueChanged],
        getter: @escaping (Base) -> T,
        setter: @escaping (Base, T) -> Void
        ) -> ControlProperty<T>