RxCocoa 是讓 Cocoa APIs 更容易使用響應(yīng)式編程的一個(gè)框架伴挚。RxCocoa 能夠讓我們方便地進(jìn)行響應(yīng)式網(wǎng)絡(luò)請(qǐng)求、響應(yīng)式的用戶(hù)交互灾炭、綁定數(shù)據(jù)模型到 UI 控件等等茎芋。而且大多數(shù)的 UIKit 控件都有響應(yīng)式擴(kuò)展,它們都是通過(guò) rx 屬性進(jìn)行使用蜈出。
demo下載
UILabel
用計(jì)時(shí)器的時(shí)間綁定到label上
let timer = Observable<Int>.interval(0.1, scheduler: MainScheduler.instance)
timer.map { String(format: "%0.2d:%0.2d:%0.1d", arguments: [($0 / 600) % 600, ($0 % 600 ) / 10, $0 % 10]) }
.bind(to: label.rx.text)
.disposed(by: disposeBag)
UIButton
- 按鈕的點(diǎn)擊事件
button.rx.tap
.subscribe(onNext:{ [weak self] in
self?.showMessage(text: "按鈕被點(diǎn)擊啦")
})
.disposed(by: disposeBag)
- 按鈕的title和image進(jìn)行綁定
//綁定title
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
timer.map { "\($0)" }
.bind(to: button.rx.title(for: .normal))
.disposed(by: disposeBag)
//綁定image(綁定backgroundImage也是一樣的)
let timer2 = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
timer2.map{
let imageName = ( $0 % 2 == 0 ? "navBack1" : "navBack3" )
return UIImage.init(named: imageName)!
}
.bind(to: button.rx.image())
.disposed(by:disposeBag)
- 按鈕的選中事件.
例子:當(dāng)其中1個(gè)按鈕選中的時(shí)候田弥,將另外2個(gè)選中取消
//將按鈕放入數(shù)組中,并進(jìn)行強(qiáng)制解包
let buttons = [button1,button2,button3].map({$0!})
button1.isSelected = true
//創(chuàng)建一個(gè)可觀察序列铡原,它可以發(fā)送最后一次點(diǎn)擊的按鈕(也就是我們需要選中的按鈕)
let selectButton = Observable.from(buttons.map({button in button.rx.tap.map{return button}}))
.merge()
//遍歷按鈕對(duì)selectedButton進(jìn)行訂閱偷厦,根據(jù)它是否是當(dāng)前選中的按鈕綁定isSelected屬性
for btn in buttons {
selectButton.map {$0 == btn}
.bind(to: btn.rx.isSelected)
.disposed(by: disposeBag)
}
- 按鈕是否可用
將UISwitch開(kāi)關(guān)事件綁定和UIButton是否可使用進(jìn)行綁定
switchs.rx.isOn.bind(to: button1.rx.isEnabled)
.disposed(by: disposeBag)
UISwitch
開(kāi)關(guān)狀態(tài)
switchs.rx.isOn.asObservable()
.subscribe(onNext:{[weak self]
print("開(kāi)關(guān)狀態(tài):\($0)")
self.button2.isEnabled = $0
})
.disposed(by: disposeBag)
UITextField
- textField的值改變
textField1.rx.text.orEmpty.asObservable()
.subscribe(onNext:{
print($0)
})
.disposed(by: disposeBag)
- 將textField的值綁定到其他UI控件上
//文本框的變化序列
let tfInput = textField1.rx.text.orEmpty.asDriver()
.throttle(0.5)
//將內(nèi)容綁定到另外一個(gè)輸入框
tfInput.drive(textField2.rx.text)
.disposed(by: disposeBag)
//將內(nèi)容綁定到label
tfInput.map({String(format: "當(dāng)前輸入了%ld個(gè)字", $0.count)})
.drive(label.rx.text)
.disposed(by: disposeBag)
//將內(nèi)容綁定到button 但輸入超過(guò)5個(gè)才可以點(diǎn)擊
tfInput.map({ $0.count > 5 })
.drive(button.rx.isEnabled)
.disposed(by: disposeBag)
- 同時(shí)監(jiān)聽(tīng)兩個(gè)textField
//同事監(jiān)聽(tīng)兩個(gè)textField
Observable.combineLatest(textField1.rx.text.orEmpty,textField2.rx.text.orEmpty){
text1,text2 -> String in
return String(format: "前1個(gè)值:%@, 后1個(gè)值:%@",text1,text2)
}
.map({$0})
.bind(to: totalLabel.rx.text)
.disposed(by: disposeBag)
事件監(jiān)聽(tīng)
通過(guò) rx.controlEvent 可以監(jiān)聽(tīng)輸入框的各種事件,且多個(gè)事件狀態(tài)可以自由組合燕刻。
- editingDidBegin:開(kāi)始編輯(開(kāi)始輸入內(nèi)容)
- editingChanged:輸入內(nèi)容發(fā)生改變
- editingDidEnd:結(jié)束編輯
- editingDidEndOnExit:按下 return 鍵結(jié)束編輯
- allEditingEvents:包含前面的所有編輯相關(guān)事件
//監(jiān)聽(tīng)textField的回車(chē)事件
textField1.rx.controlEvent(.editingDidEndOnExit)
.subscribe(onNext:{ [weak self] in
self?.textField2.becomeFirstResponder()
})
.disposed(by: disposeBag)
//監(jiān)聽(tīng)textField的所有事件
textField2.rx.controlEvent(.allEditingEvents)
.subscribe(onNext:{
print("正再監(jiān)聽(tīng)所以輸入事件")
})
.disposed(by: disposeBag)
UITextView
UITextView 還封裝了如下幾個(gè)委托回調(diào)方法:
- didBeginEditing:開(kāi)始編輯
- didEndEditing:結(jié)束編輯
- didChange:編輯內(nèi)容發(fā)生改變
- didChangeSelection:選中部分發(fā)生變化
textView.rx.didBeginEditing
.subscribe(onNext:{
print("開(kāi)始編輯")
})
.disposed(by: disposeBag)
textView.rx.didEndEditing
.subscribe(onNext:{
print("結(jié)束編輯")
})
.disposed(by: disposeBag)
textView.rx.didChange
.subscribe(onNext:{
print("內(nèi)容變了")
})
.disposed(by: disposeBag)
textView.rx.didChangeSelection
.subscribe(onNext:{
print("選擇內(nèi)容發(fā)生變化")
})
.disposed(by: disposeBag)