LoginSignup
7
7

More than 5 years have passed since last update.

RACCommandによるタップイベントの処理中にボタンの連打を防止する

Last updated at Posted at 2014-10-07

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];
    }];
}];
7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7