RxSwift ボタン連打防止


throttleOperatorを用いると良い。

throttle及び似たような機能のあるdebounceについてはこちらを参照。
RxSwiftのDebounceとThrottle
throttleはボタン連打防止、debounceはいわゆるインクリメンタルサーチなどAPI呼びすぎ防止などで使える。

実際には以下のようなextensionを作ると便利である。

Reactive+Extenstions.swift
import RxCocoa
import RxSwift

public extension Reactive where Base: UIButton {
    var throttledTap: ControlEvent<Void> {
        return ControlEvent<Void>(events: tap
            .throttle(.milliseconds(ContinuousTap.disableTapDuration), latest: false, scheduler: MainScheduler.instance))
    }
}

public extension Reactive where Base: UIBarButtonItem {
    var throttledTap: ControlEvent<()> {
        return ControlEvent<()>(events: tap
            .throttle(.milliseconds(ContinuousTap.disableTapDuration), latest: false, scheduler: MainScheduler.instance))
    }
}

public extension Reactive where Base: UITableView {
    var throttledItemSelected: ControlEvent<IndexPath> {
        return ControlEvent<IndexPath>(events: itemSelected
            .throttle(.milliseconds(ContinuousTap.disableTapDuration), latest: false, scheduler: MainScheduler.instance) )
    }
}

public extension Reactive where Base: UICollectionView {
    var throttledItemSelected: ControlEvent<IndexPath> {
        return ControlEvent<IndexPath>(events: itemSelected
            .throttle(.milliseconds(ContinuousTap.disableTapDuration), latest: false, scheduler: MainScheduler.instance) )
    }
}

enum ContinuousTap {
    /// Disable Tap Duration in Milliseconds
    static let disableTapDuration: Int = 500
}