ReactiveCocoa / ReactiveSwift

Streams of values over time

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What is an adequate ReactiveSwift solution for bidirectional binding?

markvasiv opened this issue · comments

What is an adequate ReactiveSwift solution for bidirectional binding?

Let's say I have a ViewModel which holds username property:

class ViewModel {
    let userName: MutableProperty<String?>
}

And a view, which holds a text field where the user enters username:

class ViewController {
    let viewModel: ViewModel
    var textField: TextField!
}

This view model is repososible for editing the User , which means that userName is set when current User loads and then when the user types new username in the field.

Doing something like that will result in a deadlock:

textField.text.producer.startWithValues { [weak self] (userName) in
    if self?.viewModel.userName.value != userName {
        self?.viewModel.userName.value = userName
    } 
}
    
viewModel.userName.producer.startWithValues { [weak self] (userName) in
    if self?.textField.text != userName {
        self?.textField.text = userName
    } 
}

I think that this example illustrates a somewhat common functionality among apps, so what is an adequate ReactiveSwift technique to implement it?

I was thinking of storing multiple properties inside of ViewModel (userName and loadedUserName in this example) but that increases amount of code for more complex forms and is far from elegant solution.

You should be able to do this:

textField.reactive.text <~ viewModel.userName
viewModel.userName <~ textField.reactive.continuousTextValues

Note that this uses ReactiveCocoa.

Thank you! Is that possible to do the same but with any arbitrary mutable property?

No, it's not: one needs to be the source of truth. This works with text fields (and other controls) because it doesn't update when the text field changes—only when it's edited.

But you could share a property?

Hello. 👋 Thanks for opening this issue. Due to inactivity, we will soft close the issue. If you feel that it should remain open, please let us know. 😄