2017-02-09 4 views
0

観測可能な(私の場合button.rx.tap)が3秒間のような値を出力していないかどうかを検出しようとしています。はいの場合は、ユーザーインターフェイスを更新したいと思います。ここに私の試みはこれまでのところです:RxSwiftで観測可能なイベントが特定の時間に放出されていないかどうかを検出する方法

Observable<Int>.interval(3, scheduler: MainScheduler.instance) 
    .takeUntil(button.rx.tap) // I know take until will stop the timer sequence 
    .subscribe({ event in 
     print(event) 
     UIView.animate(withDuration: 0.4, animations: { 
      if let number = event.element { 
       let scale: CGFloat = number % 2 == 0 ? 1.5 : 1.0 
       self.button.transform = CGAffineTransform(scaleX: scale, y: scale) 
      } 
     }) 
    }) 
    .addDisposableTo(disposeBag) 

私の目標は、ボタンがない3秒間タップある時はいつでもビューをアニメーション化することです。私が試したのは、スキャンdistinctUntilChangeddebounceですが、私が遭遇した演算子のほとんどは、観測可能なアイテムが放出されたときにのみアイテムを放出します。どんな助けも大歓迎です。

答えて

2
enum Event { 
case tap 
case timeout 
} 

let tapOrTimeout = button.rx.tap 
    .map { _ in Event.tap } 
    .timeout(3, scheduler: MainScheduler.instance) 
    .catchErrorJustReturn(.timeout) 

Observable.repeatElement(tapOrTimeout).concat() 
    .subscribe(onNext: { event in 
    switch event { 
    case .tap: tapHandler() 
    case .timeout: callForAttention() 
    } 
    }) 
  • timeout(_:scheduler:)何のイベントが3秒以内にチェーンの外に来ない場合は、エラーが発生します。アウト観測可能時間は、それはまた、完全な、それ故に何もその後起こりませんかどう
  • catchErrorJustReturn(_:)は、この時点で.timeoutイベント
  • にエラーを変換します。 Observable.repeatElement(_:).concat()を使用して最初にObservable<Observable<Event>>を作成し、次に内部観測値を連結します。私たちの場合は最初のものを購読し、最初のものが完了すれば同じ観察可能なものに再購読することを意味します。

我々は一度callForAttention()アニメーションを再生するだけに好む持っていた場合、私たちはこの道

let tap = button.rx.tap 
    .map { _ in Event.tap } 

let tapOrTimeout = tap 
    .timeout(3, scheduler: MainScheduler.instance) 
    .catchErrorJustReturn(.timeout) 

Observable.of(tapOrTimeout, tap).concat() 
    .subscribe(onNext: { /* same as above */}) 

以下、私たち最初のタイムアウトを行っている可能性が、ときタップのみイベントを発します発生する。

関連する問題