2017-02-09 3 views
0

관찰 가능 (내 사례 단추 .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하지만 내가 만난 조합 연산자는 대부분 관찰 가능 항목에 의해 항목이 방출 될 때만 방출 할 것이다. 어떤 도움이라도 대단히 감사합니다. 더 이벤트 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 */}) 

이 방법은, 우리 첫번째 시간 제한을 할 수 있었다, 그러나 때 탭 만 이벤트를 방출 발생합니다.