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)