rxswift 是时间监听框架,每一个事件比如文本的改变,按钮的点击或者网络请求的结束,每一个事件可以看成一个管道sequence,事件从管道流程,然后只需要监听这个管道就可以实现事件的监听
- 核心思想是Observable,即可监听的序列
- 通过DisposeBag来取消监听,所有监听后面都会增加.addDisposableTo(bag)
-
控件的监听
a. UISliderde 的监听
slider.rx.value.asObservable() .subscribe(onNext: { print("当前值为:\($0)") }) .disposed(by: disposeBag)
- 任何对象通过asObservable都可以实现监听,比如collectionView.mj_footer!.rx.refreshing.asObservable()
将UISliderde中的值赋值给UIStepper
slider.rx.value .map{ Double($0) } //由于slider值为Float类型,而stepper的stepValue为Double类型,因此需要转换 .bind(to: stepper.rx.stepValue) .disposed(by: disposeBag)
-
表中的数据刷新
let item = Observable<[SocilaModel]>.just(self.dataArr!) //或者使用 let item = Observable.from(optional: self.dataArr!)
item.bind(to: self.listTab.rx.items) { (tableView, row, element) in let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! SecondSocialTableViewCell cell.leftImageView.kf.setImage(with: URL(string: element.image_list ?? "")) cell.titleLabel.text = element.theme_name cell.descripLabel.text = element.info //cell中按钮点击事件订阅 cell.RXButton.rx.tap.asDriver() .drive(onNext: { [weak self] in self?.showAlert(title: "\(row)", message: "哈哈哈") }).disposed(by: cell.disposeBag) return cell } .disposed(by: self.disposeBag) } }
3.按钮的点击监听
button1.rx.tap.subscribe { (event) in
self.button1.setTitle("按钮1", for: .normal)
print("button1")}.addDisposableTo(self.disposeBag)
button2.rx.tap.subscribe { (event) in
self.textField2.text = "按钮2被点击了"
}.addDisposableTo(self.disposeBag)
4.监听UITextfield的文字改变
a.使用on方法实现
textField1.rx.text.subscribe { (event: Event<String?>) in
//将UITextField文字改变的内容显示在Label中
self.label1.text = event.element!
print(event.element!!)}.addDisposableTo(self.disposeBag)
textField2.rx.text.subscribe { (event: Event<String?>) in
print(event.element)//报警告 //输出: Optional(Optional("jun"))
}.addDisposableTo(self.disposeBag)
b.使用onNext方法实现
textField1.rx.text.subscribe(onNext: { (str: String?) in
self.label1.text = str!}).addDisposableTo(self.disposeBag)
c.多个textField的监听,并通过监听改变button 的透明度
Observable.combineLatest(phoneTextField.rx.text, passwordCodeTextField.rx.text)
.map({ (userName, password) in
if (userName?.count ?? 0) >= 11 && (password?.count ?? 0) >= 4 {
return CGFloat(1)
}
return CGFloat(0.2)
})
.bind(to: loginButton.rx.alpha)
.disposed(by: disposeBag)
-
Driver的使用,主要比如多次请求只需要处理一次数据
序列需要满足下面的条件才可以使用:
- 不会产生 error 事件
- 一定在主线程监听(MainScheduler)
- 共享状态变化(shareReplayLatestWhileConnected)
使用场景:
- Driver 最常使用的场景应该就是需要用序列来驱动应用程序的情况了,比如通过 CoreData 模型驱动 UI;使用一个 UI 元素值(绑定)来驱动另一个 UI 元素值
- 与普通的操作系统驱动程序一样,如果出现序列错误,应用程序将停止响应用户输入。
- 在主线程上观察到这些元素也是极其重要的,因为 UI 元素和应用程序逻辑通常不是线程安全的。
- 此外,使用构建 Driver 的可观察的序列,它是共享状态变化。
使用案例
let result = inputTF.rx.text.orEmpty
.asDriver()
.flatMap { return self.dealwithData(inputText: $0)
.asDriver(onErrorJustReturn: "检测到了错误事件") }
第一次订阅
//第一次订阅,并把内容绑定到另一个UILabel上
result.map{ "长度:\( ($0 as! String).count )" }
.drive(self.textLabel.rx.text)
.disposed(by: disposeBag)
//第二次订阅,并把内容绑定到另一个UIButton上
result.map { "\($0 as! String)"}
.drive(self.btn.rx.title())
.disposed(by: disposeBag)
-
改变label 中文字
label1.rx.observe(String.self, "text") .subscribe(onNext: { (str: String?) in print(str!)}).addDisposableTo(disposeBag) label2.rx.observe(CGRect.self, "frame") .subscribe(onNext: { (rect: CGRect?) in print(rect!.width)}).addDisposableTo(disposeBag)
7.监听UIScrollView的滚动
scrollView.contentSize = CGSize(width: 1000, height: 0)
scrollView.rx.contentOffset.subscribe(onNext: { (point : CGPoint) in
print(point)}).addDisposableTo(disposeBag)
网友评论