2013-03-08 79 views
3

我正在试验Reactive Cocoa,我无法合并来自多个UIControls的信号。RACSignal combineLatest使用多个UIControls

我正在为UIEdgeInsets创建一个编辑器,并有四个UISteppers,用于顶部,左侧,底部和右侧的插图。

做的是这样的:

RAC(self.insets) = [RACSignal combineLatest:@[ 
      [topStepper rac_signalForControlEvents:UIControlEventValueChanged], 
      [leftStepper rac_signalForControlEvents:UIControlEventValueChanged], 
      [bottomStepper rac_signalForControlEvents:UIControlEventValueChanged], 
      [rightStepper rac_signalForControlEvents:UIControlEventValueChanged] 
      ] reduce:^(UIStepper *top, UIStepper *left, UIStepper *bottom, UIStepper *right) { 
       return [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(top.value, left.value, bottom.value, right.value)]; 
      }]; 

然而,这决不会导致正在处理的信号。

如果我只包括一个信号,就像这样:

RAC(self.insets) = [RACSignal combineLatest:@[ 
    [topStepper rac_signalForControlEvents:UIControlEventValueChanged]] 
    reduce:^(UIStepper *top) { 
     return [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(top.value, 0.0,0.0,0.0)]; 
    }]; 

它将按预期工作(观察其他任何步进电机的独立工作正常,以及),但多个控件,我什么也没得到。我可以通过观察每个控件作为一个单独的信号解决问题,但似乎错过了combineLatest方法的要点。我做错了什么,或者我应该提出有关RAC项目的问题?

回答

6

这是因为为了运行combineLatest:reduce:,该阵列中的每个控件都必须广播至少一个开始的信号(观察最近的信号的任何非变异值都不会调用reduce块)。您可以清楚地看到它,因为每个控件都必须至少点击一次才能开始生成有效的信号,然后按照您的预期进行处理和处理。正如由Justin指出,可以使信号有一个初始值,这应该得到正确的价值观和运行远远超过调用-sendActionForControlEvent:

RAC(self.insets) = [RACSignal combineLatest:@[ 
        [[self.topStepper rac_signalForControlEvents:UIControlEventValueChanged]startWith:nil], 
        [[self.leftStepper rac_signalForControlEvents:UIControlEventValueChanged]startWith:nil], 
        [[self.bottomStepper rac_signalForControlEvents:UIControlEventValueChanged]startWith:nil], 
        [[self.rightStepper rac_signalForControlEvents:UIControlEventValueChanged]startWith:nil] 
        ] reduce:^(UIStepper *top, UIStepper *left, UIStepper *bottom, UIStepper *right) { 
         return [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(top.value, left.value, bottom.value, right.value)]; 
        }]; 
+0

有道理更快,但它是肮脏的。 – jrturton 2013-03-08 16:41:54

+1

你可以使用'-startWith:'给一个信号一个初始值。另外,nil值不会取消'+ combineLatest:'。他们会像其他任何值一样进入reduce块。 – 2013-03-08 18:12:26

+0

@ JustinSpahr-Summers当我用他的代码进行测试时,在所有四个步进值发生了变异之前,不会调用reduce块和setter。也许取消不是正确的选择。 – CodaFi 2013-03-08 18:36:30