元ネタ: Command which sends alternating YES/NO values · Issue #767 · ReactiveCocoa/ReactiveCocoa
ボタン・ジェスチャーなどのUI操作とRACSignal
を仲介するクラスとしてRACCommand
があります。これを用いて、状態(フラグとなるインスタンス変数/プロパティ)を持たずにトグルボタンを表現するパターンです。
// ブロックの戻り値が`[command execute:senderOrValue]`の戻り値となる。
RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(id _) {
return [RACSignal return:RACUnit.defaultUnit];
}];
RACSignal *alternating = [[[command.executionSignals // `-execute:`の度にその戻り値のシグナルを送るシグナル。
flatten]
startWith:RACUnit.defaultUnit] // ユーザー操作前に初期値がセットされるようにする。
scanWithStart:@NO combine:^(NSNumber *previous, id _) {
// 前回の値を反転したブール値を返し、
// コマンドの実行によって得られた値は無視する(_ == RACUnit.defaultUnit)。
//
// 最初に`@NO`を反転するため、シグナルの初回の値は`@YES`となる。
return @(!previous.boolValue);
}];
RAC(self, onOff) = alternating;
// `UIControlEventTouchUpInside`のイベントで`-execute:`される。
button.rac_command = command;