利用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