利用RxSwift 實現倒計時,須要 依靠 takeWhile
來判斷爲真的條件,不然序列就會一直計時下去 主要代碼以下 這麼一大坨bash
viewModel.getSMScodeAction.elements.observeOn(MainScheduler.instance).subscribe(onNext: { [weak self](model) in guard let self = self else { return } self.viewModel.getSMSEableObserable.accept(false) let mapResult:Observable<Int> = Observable<Int>.interval(1, scheduler: MainScheduler.instance).map { (second) -> Int in return TOTAL_SECOND - second } mapResult.takeWhile { $0 > 0 }.subscribe(onNext: { [weak self](remind) in guard let self = self else { return } self.smsBtn.setTitle("\(remind)s", for: .normal) }, onCompleted: { self.smsBtn.setTitle("再次獲取", for: .normal) self.viewModel.getSMSEableObserable.accept(true) }).disposed(by: self.disposeBag) }, onError: { (error) in }).disposed(by: disposeBag) 複製代碼
viewModel.getSMScodeAction.elements.observeOn(MainScheduler.instance
返回一個在主線程 上的 Obserable, 訂閱它,獲得的是,點擊 獲取驗證碼,執行網絡請求的成功的的 閉包{} ,要在這裏去實現 倒計時。 其中 viewModel.getSMScodeAction
是一個 Action
Action 是這樣的一個類markdown
public final class Action<Input, Element>
複製代碼
一個輸入,和一個 Element
,裏面的 elements
是 Action
的一個屬性,是一個 Observable
網絡
public let elements: Observable<Element> 複製代碼
Observable<Int>.interval(1, scheduler: MainScheduler.instance)
是一個 間隔爲 1 的 Observable 使用 map 函數,轉換成 剩餘的時間,類型不變,意義變了閉包
這裏的 takeWhile 表示 mapResult 繼續執行的條件,倒計時的時間 大於 0 就執行, 不然就停下來,從新獲取函數
mapResult.takeWhile { $0 > 0 }.subscribe(onNext: { [weak self](remind) in guard let self = self else { return } self.smsBtn.setTitle("\(remind)s", for: .normal) }, onCompleted: { self.smsBtn.setTitle("再次獲取", for: .normal) self.viewModel.getSMSEableObserable.accept(true) }).disposed(by: self.disposeBag) 複製代碼
當 takeWhil
e 的條件不符合的時候,直接終止,走 onCompleted{}
, 並不會跳過 當前值spa
例如線程
let disposeBag = DisposeBag() Observable.of(1, 2, 3, 4, 3, 2, 1) .takeWhile { $0 < 4 } .subscribe(onNext: { print($0) }) .disposed(by: disposeBag) 複製代碼
到前面的 1,2,3,就終止了 4 後面的不會再輸出code