3

Reactive Cocoaを試していますが、複数の UIControl からの信号を組み合わせるのに問題があります。

UIEdgeInsets のエディターを作成しており、上、左、下、右のインセット用に 4 つの 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)];
          }];

ただし、これによって信号が処理されることはありません。

次のように、シグナルを 1 つだけ含める場合:

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 プロジェクトで問題を提起する必要がありますか?

4

1 に答える 1

7

これは、実行するためにcombineLatest:reduce:、その配列内の各コントロールが開始するシグナルを少なくとも 1 つブロードキャストする必要があるためです (最新のシグナルを観察するための変更されていない値は、reduce ブロックを呼び出しません)。これらのコントロールのそれぞれを少なくとも 1 回タップして有効な信号を生成し始める必要があるため、これは非常に明確にわかります。信号はスローされ、期待どおりに処理されます。ジャスティンが指摘したように、信号に初期値を持たせることができます。これにより、適切な値を取得して、呼び出すよりもはるかに速く実行できます-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)];
                    }];
于 2013-03-08T16:35:54.607 に答える