ReactiveCocoaを使っている場合、ボタンのタップ処理などはRACCommandを使って処理することが多いかと思いますが、その際ボタンの連打を防止するにはどうするればよいか考えてみました。
button.rac_command = [[RACCommand alloc] initWithEnabled:button.rac_command.executing.not signalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// なが〜い処理
// 成功時はコッチ
[subscriber sendNext:nil];
[subscriber sendCompleted];
// エラー時はコッチ
[subscriber sendError:nil];
}];
}];
連打を防止する上で重要なのは1行目のコードです。
これでシグナル(なが〜い処理の部分)の実行状態に応じたシグナルを取得することができます。
なお実行中は「YES」が、実行されていない時は「NO」が返ります。
これをinitWithEnabledに渡してしまうと、処理が停止しているときにボタンが非活性になってしまうので、notプロパティを使い、逆のシグナルを返すようにします。
button.rac_command.executing.not
ちなみに、シグナルの処理結果を得る場合は、以下のように書けばOKです。
// 成功時の結果を受け取る場合
[button.rac_command.executionSignals.flatten subscribeNext:^(id x) {
// なが〜い処理の結果が「x」に入っている
}];
// エラー時を受け取る場合
[button.rac_command.errors subscribeNext:^(id x) {
// なが〜い処理で発生したエラーが「x」に入っている
}];
(2014/10/07 19:54追記)
よくよく検証してみたら、initWithEnabledにシグナルを渡す必要すらありませんでした。。
なので、以下のコードだけでシグナル実行中のボタンの制御が行われます。
button.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// なが〜い処理
// 成功時はコッチ
[subscriber sendNext:nil];
[subscriber sendCompleted];
// エラー時はコッチ
[subscriber sendError:nil];
}];
}];