Search code examples
iosswiftreactive-cocoa

How to bind Signal<Bool, NoError> to enabled property of UIButton in Reactive Cocoa 4


I have a very simple use case for ReactiveCocoa. In my setup, I have two UITextFields and one UIButton.

The button's enabled property should only be set to true iff both textfields contain at least one character.

I started out creating a Signal<Bool, NoError> that emits true or false depending on the the above mentioned condition.

Now, as far as I understand I somehow need to bind the signal (or its values) to the enabled property of my button. But I have no clue how to do this and more than an hour of research haven't lead to any results...

UPDATE: From what I understand, this could previously be achieved using the RAC macro: RAC(self.button, enabled) = signal;, or something along those lines. But that doesn't help me since the macros have been deprecated in RAC 3. My question is basically the same as this one only for RAC 4 instead of 3.


Solution

  • This can be achieved using the custom <~ operator. However, it only works on properties of type MutableProperty, so we can't just do the following:

    let signal: <Bool, NoError> = ...
    button.enabled <~ signal
    

    Instead, we need to wrap the button's enabled property in a MutableProperty like so:

    extension UIButton {
        public var rac_enabled: MutableProperty<Bool> {
            return lazyMutableProperty(self, key: &AssociationKey.text, setter: { self.enabled = $0 }, getter: { self.enabled })
        }
    }
    

    Note that this implementation depends on this gist which was created by Colin Eberhardt.

    Now we can just do:

    button.rac_enabled <~ signal