如何使用ReactiveCocoa影响多个属性?

时间:2013-11-07 20:50:20

标签: ios objective-c reactive-cocoa

我想在UIButton上影响多个属性,并且还有一个活动命令。

我试图推断最佳方法,但可以使用一些输入。

这就是我所拥有的:

// Listen for changes on the textfields, alter the button UI state
[[RACSignal
  combineLatest:@[ _usernameField.rac_textSignal,_passwordField.rac_textSignal]
  reduce:^id(NSString *username, NSString *password) {
      BOOL valid = [username length] >= 4 && [password length] >= 4;
      _loginButton.enabled = valid;
      _loginButton.alpha = valid ?: 0.65;
      return nil;
  }] subscribeCompleted:^{}];

// Listen for taps
_loginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    NSLog(@"Tap");
    return [RACSignal empty];
}];

这很有效,但我很乐意听到任何建议。

2 个答案:

答案 0 :(得分:6)

不要考虑如何一次更新多个属性,将每个属性视为随时间变化的值可能会有所帮助。

因此,您可以使用自己的信号(值流)对每个属性建模,重用一个常见的" base"流以避免重复重要的逻辑:

RACSignal *valid = [RACSignal
    combineLatest:@[ _usernameField.rac_textSignal, _passwordField.rac_textSignal ]
    reduce:^(NSString *username, NSString *password) {
        return @([username length] >= 4 && [password length] >= 4);
    }];

RAC(_loginButton, enabled) = valid;
RAC(_loginButton, alpha) = [valid map:^(NSNumber *b) {
    return @(b.boolValue ? 1 : 0.65);
}];

这也有避免任何副作用的好处。

答案 1 :(得分:0)

JFI我使用多个赋值将多个属性绑定到一个信号。像这样。在我的脑海中读起来很漂亮。

RAC(self.channelLabel, textColor) = 
RAC(self.roomNameTextField, textColor) = [RACObserve(self, roomImage) map:^id(id value) {
    return value ? [UIColor whiteColor] : [UIColor blackColor];
}];