I'm building an iOS social client, and in the "compose" view, I've got a UITextView
where the user enters text. I'd like to use ReactiveCocoa to bind the text
of the UITextView
to the NSString
of the data model, to follow MVVM.
However, I'm running into several issues, all related to a single thing: the RACObserve
block doesn't get called when the UITextView
's text is changed programmatically.
(An example: I change the text into an attributed string to highlight #hashtags, @usernames, etc, but this attributed string doesn't get created when the view is programmatically changed.)
In my previous question on this topic, I got some helpful advice that I should bind the textview to the model - and vice versa - but it's not clear to me how I should do it with the current version of Reactive Cocoa. The sample code that I've managed to find calls APIs that are now deprecated.
What's the appropriate way to bind the rac_textSignal
of a UITextView
to an NSString
(and vice versa) so that I can reliably call a block of code when the contents of the UITextView
are changed (whether programmatically or by the user)?
The answer depends on whether the binding between the view model's text
and the UITextView
s text
needs to be bidirectional. Generally we try to stay away from bidirectional bindings because they become harder to reason about. Ideally only one direction is driving the data.
So in that case, you'd write something like:
RAC(self.viewModel, text) = [RACSignal merge:@[
[self.textView rac_textSignal],
RACObserve(self.textView, text),
]];
That way you're picking up on changes to both the UITextView
s text
property directly, and text changes that come from the user typing.