“结合最新”与ReactiveCocoa和信号信号

时间:2013-10-08 05:27:50

标签: objective-c reactive-cocoa

在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 个答案:

答案 0 :(得分: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];