观察者(Observer)的作用就是监听事件,然后对这个事件做出响应。或者说任何响应事件的行为都是观察者.
创建观察者
1.直接在 subscribe、bind 方法中创建观察者
- 在 subscribe 方法中创建
创建观察者最直接的方法就是在 Observable 的 subscribe 方法后面描述,当事件发生时,需要如何做出响应。观察者就是由后面的 onNext,onError,onCompleted 这些闭包构建出来的。
/// 5s后,每隔一秒,发出一个事件;10s后dispose()
let observable13 = Observable<Int>.timer(5, period: 1, scheduler: MainScheduler.instance)
let subscription = observable13.subscribe(onNext: { (event) in
print("timer()__\(event)")
}, onError: { (error) in
print("timer()__\(error)")
}, onCompleted: {
print("timer()__onCompleted")
}) {
print("timer()__onDisposed")
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 10.0) {
subscription.dispose()
}
//timer()__0
//timer()__1
//timer()__2
//timer()__3
//timer()__4
//timer()__5
//timer()__onDisposed
- 在bind方法中创建
let label = UILabel(frame: CGRect.init(x: 100, y: 150, width: 200, height: 20))
label.textColor = UIColor.black
self.view.addSubview(label)
//Observable序列(每隔1秒钟发出一个索引数)
let observable2 = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
let subscription = observable2
.map { "当前索引数:\($0 )"}
.bind{ text in
label.text = text
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
subscription.dispose()
}
页面每隔一秒钟+1, 5s后结束.png
2.使用 AnyObserver 创建观察者
- 配合subscribe使用
let observable2 = Observable.from(["A", "B", "C"])
//观察者
let observer: AnyObserver<String> = AnyObserver { (event) in
switch event {
case .next(let data):
print(data)
case .error(let error):
print(error)
case .completed:
print("completed")
}
}
observable2.subscribe(observer)
//A
//B
//C
//completed
- 配合bind使用
let observable2 = Observable.from(["A", "B", "C"])
//观察者
let observer: AnyObserver<String> = AnyObserver { (event) in
switch event {
case .next(let data):
print(data)
case .error(let error):
print(error)
case .completed:
print("completed")
}
}
observable2.bind(to: observer).disposed(by: disposeBag)
3.使用Binder 创建观察者
相较于AnyObserver 的大而全,Binder 更专注于特定的场景。Binder 主要有以下两个特征:
- 不会处理错误事件; 确保绑定都是在给定 Scheduler 上执行(默认 MainScheduler)
- 一旦产生错误事件,在调试环境下将执行 fatalError,在发布环境下将打印错误信息
let label = UILabel(frame:CGRect.init(x: 20, y: 100, width: 300, height: 30))
label.textColor = UIColor.black
self.view.addSubview(label)
//观察者
let observer: Binder<String> = Binder(label) { (view, text) in
//收到发出的索引数后显示到label上
view.text = text
}
//Observable序列(每隔1秒钟发出一个索引数)
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
let subscription = observable
.map { "当前索引数:\($0 )"}
.bind(to: observer)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
subscription.dispose()
}
每隔1s+1,5s后停止.png
4.自带的可绑定属性
例如:label.rx.text
let label = UILabel(frame: CGRect.init(x: 100, y: 150, width: 200, height: 20))
label.textColor = UIColor.black
self.view.addSubview(label)
//Observable序列(每隔1秒钟发出一个索引数)
let observable2 = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
let subscription = observable2
.map { "当前索引数:\($0 )"}
.bind(to: label.rx.text)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
subscription.dispose()
}
5.自定义可绑定属性
- 通过拓展,使用BInder创建观察者.
extension UILabel {
public var fontSize: Binder<CGFloat> {
return Binder(self) { label, fontSize in
label.font = UIFont.systemFont(ofSize: fontSize)
}
}
}
测试使用情况
let label = UILabel(frame: CGRect.init(x: 100, y: 150, width: 200, height: 200))
label.textColor = UIColor.black
label.text = "我是文字"
self.view.addSubview(label)
//Observable序列(每隔0.5秒钟发出一个索引数)
let observable = Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
let subscription = observable
.map { CGFloat($0)*5 }
.bind(to: label.fontSize) //根据索引数不断变放大字体
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
subscription.dispose()
}
2.通过对 Reactive 类进行扩展
extension Reactive where Base: UILabel {
public var fontSize: Binder<CGFloat> {
return Binder(self.base) { label, fontSize in
label.font = UIFont.systemFont(ofSize: fontSize)
}
}
}
测试使用
let label = UILabel(frame: CGRect.init(x: 100, y: 150, width: 200, height: 200))
label.textColor = UIColor.black
label.text = "我是文字"
self.view.addSubview(label)
//Observable序列(每隔0.5秒钟发出一个索引数)
let observable = Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
let subscription = observable
.map { CGFloat($0)*5 }
.bind(to: label.rx.fontSize) //根据索引数不断变放大字体
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 5.0) {
subscription.dispose()
}
网友评论