2017-02-09 30 views
0

我試圖檢測是否可觀察(我的情況button.rx.tap)沒有發出任何值說3秒。如果是,我想更新用戶界面。這裏是我的嘗試至今:如何檢測是否一個observable沒有發射任何事件在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) 

我的目標是每當按鈕不被竊聽三秒鐘的動畫視圖。我已嘗試掃描,distinctUntilChanged反彈但我遇到的大多數組合運算符只會在某個項目由可觀察項發出時纔會發射項目。任何幫助深表感謝。如果沒有事件出來鏈的3秒內

回答

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:)會引發錯誤。
  • 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 */}) 

這樣,我們先暫停,但隨後只在水龍頭髮出事件發生。

相關問題