RxSwift 常用操作符
使用场景
- 验证码输入框
TextField
操作符: BahaviorReplay
bind
1 2 3 4 5 6 7 8 9 10 11 12 13
| let codeReplay = BehaviorReplay(value: "") let codeTextField = UITextField()
codeTextField.rx.text.orEmpty .map({text -> String i n guard text.isMatching("[\\d]*") else { return codeReplay.value } return String(text.prefix(6)) }) .bind(to: codeReplay) .disposed(by: disBag)
codeReplay.bind(to: codeTextField.rx.text).disposed(by: disBag)
|
- 单选按钮点击
UIButton
操作符: distinctUntilChanged
bind
map
merge
map
原理
map 操作符将源Observable 的每个元素应用提供的转换方法, 然后返回含有转换结果的 Observable.
distinctUntilChanged
原理
distinctUntilChanged
操作符阻止 Observable 发出相同元素. 如果后一个元素和前一个元素是相同的, 这个元素就不会被发出来. 如果后一个元素和前一个元素不相同, 那么这个元素才会被发出来.
merge
merge 主要就是将多个 Observables 合并成一个
应用场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| enum ContactType { case 员工 case 经理 }
let employeeButton = UIButton() let managerButton = UIButton() let contactSubject = PublishSubject<ContactType>(value: .员工) Observable<ContactType> .merge( employeeButton.rx.tap.asObservable().map{.员工}, managerButton.rx.tap.asObservable().map{.经理} ) .distinctUntilChanged() .bind(to: contactSubject)
两个按钮只能选其一, 通过 merge 操作符, 合并多个序列: 两个按钮点击事件转成可观察序列, 然后通过 map 操作符应用提供的转换方法 map{.员工/经理} 转成Observable<ContactType>带有元素(不同枚举的)序列; 调用 distinctUntilChanged 只会拿到不同元素的时候才会触发,将新元素发出去. 最后将带有新元素的序列Observable<ContactType>绑定到 contactSubject 可观察序列上.
contactSubject.subscribe(onNext: {[weak self] contact in guard let self = self else {return} employeeButton.isSelected = contact == .员工 managerButton.isSelected = contact == .经理 }) .disposed(by: disposeBag)
最后去订阅这个 contactSubject 可观察序列, 就能在发出新元素的时候 去设置按钮的选中状态, 达到只有一个被选中的效果了. 完~~
|
按钮点击带参数调用接口
例如: 获取验证码按钮 点击按钮, 伴随着指示器的转圈, 调用接口 按钮进行倒计时并且不可点击
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| let codeButton = UIButton()
let codeNetworking = ActivityIndicator() let timer = XTimer()
Observable.combineLatest( codeNetworking.asObservable(), timer.isRunning.asObservable() ) .map { !($0 || $1)} .bind(to: codeButton.rx.isEnable) .disposed(by: disposeBag)
networking.asObservable().bind(to: rx.animated).disposed(by: disposeBag)
let paramsOfCode = Observable .combineLatest(subject1, subject2) .map{(subj1: $0.0, subj2: $0.1)} .share(1)
withLatestFrom: 拿到最新的参数序列 flatMapLatest: 将 paramsOfCode这个可观察序列的元素转换成其他的可观察序列, 然后取这些 Observables 中最新的一个
codeButton.rx.tap .withLatestFrom(paramsOfCode) .flatMapLatest({ params -> Observable<string> in
return VerifyApi.share .request(target, mapModel: Void.self) .trackActivity(codeNetworking) .flatMap({ result -> Observable<string> in switch result { case .sucess(_): return timer.fire().asObservable() case .failure(_, let errmsg): print("错误") return .empty() } }) }) .bind(to: codeButton.rx.title()) .disposed(by: disposeBag)
|