Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a UISwitch's state to a model with ReactiveCocoa

I am trying to bind a UISwitch's on state to a boolean property in my model using ReactiveCocoa. I started with:

RACChannelTo(self.switch, on, @NO) = RACChannelTo(self.model, toggle, @NO);

This is how I've been binding other views to other parts of my model, unfortunately it didn't appear to do anything for the UISwitch. The model's state does not affect the switch, or vice versa.

So I tried:

RACChannelTo(self.model, toggle, @NO) = [self.switch rac_newOnChannel];

This appears to work ok, but I have to manually set up the switch's state beforehand. So, right now I have:

self.switch.on = self.model.toggle;
RACChannelTo(self.model, toggle, @NO) = [self.switch rac_newOnChannel];

Again, this works, but it seems very inelegant compared to using ReactiveCocoa with other controls.

Isn't there a better way to do this?

like image 468
Andy Molloy Avatar asked Oct 01 '22 09:10

Andy Molloy


1 Answers

You're spot-on to use -rac_newOnChannel instead of a channel to the switch's on. That's because on isn't guaranteed to be modified in a KVO-compliant way. Using the channel hooks into the switch's UIControlEventValueChanged event.

To get behavior like:

RACChannelTo(self.switch, on, @NO) = RACChannelTo(self.model, toggle, @NO);

Where the switch starts with the value from the model, you can do the channel hook-up manually:

RACChannelTerminal *switchTerminal = [self.switch rac_newOnChannel];
RACChannelTerminal *modelTerminal = RACChannelTo(self.model, toggle, @NO);
[modelTerminal subscribe:switchTerminal];
[[switchTerminal skip:1] subscribe:modelTerminal];
like image 184
joshaber Avatar answered Oct 13 '22 10:10

joshaber