2013-10-08 82 views
4

在ReactiveCocoa中实现“结合最新”信号信号的最佳方法是什么?我有以下问题:“结合最新”与ReactiveCocoa和信号信号

给定N个文本字段,订阅UIControlEditingEventChanged事件,并根据调用的值创建一个新的信号。订阅每个订阅者完成一次,然后将这些值相互结合使用。因此,这里是我的本钱:

__block NSMutableSet *subscriptions = [NSMutableSet set]; 
RACSignal *validationSignals = [[[[TEXT_FIELDS rac_sequence].signal flattenMap:^RACStream* (UITextField *textField) { 
    return [textField rac_signalForControlEvents:UIControlEventEditingChanged]; 
}] flattenMap:^RACStream *(UITextField* textField) { 
    if(![subscriptions containsObject:textField]) { 
     [subscriptions addObject:textField]; 
     return [textField rac_validationSignal]; 
    } 
    return [RACSignal empty]; 
}]]; 

哪里rac_validationSignal是UITextFields我自己的类处理验证。信号正确地通过,但一次只有一个。我需要一次性购买所有订阅的价值,以获得所有编辑字段的有效性。

编辑:

一种可能的解决方案涉及一个可变的数组,我添加新的字段并如我通常会发送该组合信号。这似乎相当不错,还有其他想法?

__block NSMutableSet *subscriptions = [NSMutableSet set]; 
__block NSMutableArray *signals = [NSMutableArray array]; 
RAC(self.editButton, enabled) = 
[[[[TEXT_FIELDS rac_sequence].signal flattenMap:^RACStream* (UITextField *textField) { 
    return [textField rac_signalForControlEvents:UIControlEventEditingChanged]; 
}] flattenMap:^RACStream *(UITextField* textField) { 
    if(![subscriptions containsObject:textField]) { 
     [subscriptions addObject:textField]; 
     [signals addObject:[textField rac_validationSignal]]; 
     return [RACSignal combineLatest:signals]; 
    } 
    return [RACSignal empty]; 
}] map:^NSNumber *(RACTuple *value) { 
    for(NSNumber *isValid in value) { 
     if(![isValid boolValue]) { return @(NO); } 
    } 
return @(YES); 
}]; 

谢谢!

回答

1

你可以试试这个:

NSArray *TEXT_FIELDS = @[[txt1.rac_textSignal distinctUntilChanged],[txt2.rac_textSignal distinctUntilChanged]]; 
[[RACSignal combineLastest:TEXT_FIELDS reduce:^ (NSSTring *txt1, NSString *txt2) { 
    // Return your validate method here 
    // Signal only send `next` value it is different from previous `next` value 
    return [self inputvalication]; 
}] setKeyPath:@"enabled" onObject:self.myButton]; 
+0

这不会做同样的事情,因为我一直在寻找。 'combineLatest'接受一个“静态”信号阵列。我对每次用户在字段中输入时都会更新的动态数组感兴趣。查看我的示例解决方案,查找我正在寻找的示例。 –

+0

@MikkoHarju,对不起,我还是不明白,'rac_textSignal'每次用户在字段中输入时都会更新,它不是静态的。 – babygau

+0

如果我应该从所有文本字段中创建一个数组并在其上运行'combineLatest',那么信号将包含所有这些字段的内容,并且根据我在哪里订阅'rac_textSignal',它可能会返回空字符串或实际值在田野上。 我只对那些实际上由用户修改的人感兴趣。这就是为什么我只在为给定字段触发'UIControlEventEditingChanged'事件后订阅。 –