2017-02-09 27 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 */}) 

这样,我们先暂停,但随后只在水龙头发出事件发生。

相关问题