扬庆の博客

RxSwift常用操作符

字数统计: 828阅读时长: 3 min
2021/04/15 Share

RxSwift 常用操作符

使用场景

  1. 验证码输入框 TextField

操作符: BahaviorReplay bind

1
2
3
4
5
6
7
8
9
10
11
12
13
// 只能输入 6 位数字
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)
  1. 单选按钮点击 UIButton

操作符: distinctUntilChanged bind map merge

map 原理

map

map 操作符将源Observable 的每个元素应用提供的转换方法, 然后返回含有转换结果的 Observable.

distinctUntilChanged原理

distinctUntilChanged

distinctUntilChanged 操作符阻止 Observable 发出相同元素. 如果后一个元素和前一个元素是相同的, 这个元素就不会被发出来. 如果后一个元素和前一个元素不相同, 那么这个元素才会被发出来.

merge

merge 主要就是将多个 Observables 合并成一个

merge

应用场景

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()

// 控制 codeButton 的 isEnable 参数
Observable.combineLatest(
codeNetworking.asObservable(),
timer.isRunning.asObservable()
)
.map { !($0 || $1)}
.bind(to: codeButton.rx.isEnable)
.disposed(by: disposeBag)

// 将可观察序列绑定到 rx.animated , 一旦networking 被订阅即执行 animated
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
// 判断参数格式是否正确, 不正确给弹框提醒
// 返回一个可观察序列带有字符串元素的 Observable<string>

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)




CATALOG
  1. 1. RxSwift 常用操作符
    1. 1.0.1. map 原理
    2. 1.0.2. distinctUntilChanged原理
    3. 1.0.3. merge
    4. 1.0.4. 按钮点击带参数调用接口