2013-03-08 26 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