摘要:當(dāng)Swift迅速崛起、并漸漸取代oc成功iOS開發(fā)的首選語(yǔ)言的時(shí)候缀拭,Swift的相關(guān)框架也是如雨后春筍般冒了出來(lái)犬耻。RxSwift作為響應(yīng)式編程的框架。既能完美兼容Swift勋乾,又能強(qiáng)健項(xiàng)目架構(gòu)宋下。很強(qiáng)大。
前段時(shí)間辑莫,公司也是用RxSwift的架構(gòu)重構(gòu)了公司項(xiàng)目学歧。RxSwift雖然語(yǔ)法簡(jiǎn)潔精煉,可以很大程度上減少代碼數(shù)量各吨。但其中也存在一些坑枝笨,也不知是自己理解不到位還是確實(shí)是坑。在此記錄下來(lái)揭蜒。避免以后遇到不知所措
-
UITableView的左滑刪除
-
場(chǎng)景描述:
tableView的DataSource是用RxSwift雙向綁定的横浑,row的點(diǎn)擊也是通過RxSwift來(lái)監(jiān)聽的。但我設(shè)置tableView的代理給ViewController(控制器)忌锯,并實(shí)現(xiàn)左滑刪除的代理時(shí)伪嫁。發(fā)現(xiàn)該代理不起作用。
有區(qū)別的主要代碼如下
/// 聲明一個(gè)可被觀察的數(shù)組
var arr = Variable<[XYJPersonMsg]>([])
// 綁定數(shù)據(jù)源
_ = arr.asObservable().bind(to: tableView.rx.items(cellIdentifier: XYJPersonMsgCell.cellIdentifi, cellType: XYJPersonMsgCell.self)) { row, element, cell in
cell.model = element
// 隱藏mj_footer
self.tableView.mj_footer.isHidden = self.tableView.mj_footer.frame.origin.y <= self.tableView.frame.maxY
}
// 設(shè)置代理
tableView.rx.setDelegate(self).disposed(by: disposeBag)
-
解決問題:
將該控制器中的RxSwift實(shí)現(xiàn)方式改成常用的設(shè)置代理的方式實(shí)現(xiàn)
有區(qū)別的主要代碼如下:
var arr = [XYJPersonMsg]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return self.arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let cell: XYJPersonMsgCell = tableView.dequeueReusableCell(withIdentifier: XYJPersonMsgCell.cellIdentifi) as? XYJPersonMsgCell ?? XYJPersonMsgCell.init(style: .default, reuseIdentifier: XYJPersonMsgCell.cellIdentifi)
cell.model = self.arr[indexPath.row]
// 隱藏mj_footer
self.tableView.mj_footer.isHidden = self.tableView.mj_footer.frame.origin.y <= self.tableView.frame.maxY
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = XYJPersonDetailVC()
vc.title = "個(gè)人消息"
vc.personModel = self.arr[indexPath.row]
// 更新閱讀狀態(tài)
self.arr = self.arr.enumerated().map({ (index,model) -> XYJPersonMsg in
if indexPath.row == index {
model.read_flag = 2
}
return model
})
tableView.reloadData()
self.navigationController?.pushViewController(vc, animated: true)
}
公共的代理代碼
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
let deleteAction = UITableViewRowAction.init(style: .default, title: " ", handler: { (action, indexPath) in
print("刪除")
let personModel = self.arr[indexPath.row] as XYJPersonMsg
self.deleteMsgStatus(parameters: ["id": personModel.id ?? 0,"read_flag": "3"], row: indexPath.row)
})
deleteAction.backgroundColor = UIColor.backgroundColor
let cancleACtion = UITableViewRowAction.init(style: .default, title: " ", handler: { (action, indexPath) in
print("取消")
tableView.reloadData()
})
cancleACtion.backgroundColor = UIColor.backgroundColor
return [deleteAction, cancleACtion]
}
-
UITextField的循環(huán)監(jiān)聽
- 場(chǎng)景描述: UITextField一開始不能輸入偶垮,當(dāng)UITextField賦值后张咳,可以改變UITextField的內(nèi)容
主要實(shí)現(xiàn)如下:
設(shè)置UITextField的enable為false
首先將UITextField的text綁定到VM的textValue上。
當(dāng)設(shè)置UITextField的text的值得時(shí)候似舵,再設(shè)置textValue的值
// 主要代碼代碼如下
realNameView.cardField.field.rx.text.orEmpty.asObservable().bind(to: vm.IDCardNumValue).disposed(by: disposeBag)
self.realNameView.cardField.field.rx.text.orEmpty.asObservable().bind(to: self.vm.IDCardNumValue).disposed(by: self.disposeBag)
self.vm.IDCardNumValue.asObservable().subscribe(onNext: { (idno) in
self.realNameView.cardField.field.text = idno
}).disposed(by: self.disposeBag)
self.vm.IDCardNumValue.value = idno
這樣會(huì)出現(xiàn)當(dāng)你賦值完后脚猾,再輸入的時(shí)候會(huì)出現(xiàn)輸一個(gè)值,UITestField里面會(huì)出現(xiàn)幾個(gè)相同的值砚哗,比如龙助。輸入一個(gè)a,UITestField里面會(huì)出現(xiàn)好多個(gè)a
改進(jìn):
設(shè)置UITextField的enable為false
首先將UITextField的text綁定到VM的textValue上。
監(jiān)聽textValue并設(shè)置UITextField的text的值得時(shí)候提鸟,再設(shè)置textValue的值
// 主要代碼如下
realNameView.cardField.field.rx.text.orEmpty.asObservable().bind(to: vm.IDCardNumValue).disposed(by: disposeBag)
self.realNameView.cardField.field.rx.text.orEmpty.asObservable().bind(to: self.vm.IDCardNumValue).disposed(by: self.disposeBag)
self.vm.IDCardNumValue.asObservable().take(2).subscribe(onNext: { (idno) in
self.realNameView.cardField.field.text = idno
}).disposed(by: self.disposeBag)
self.vm.IDCardNumValue.value = idno
-
按鈕的多次監(jiān)聽
- 場(chǎng)景描述: UI界面的View會(huì)刷新(創(chuàng)建->移除->重新創(chuàng)建)军援,在這個(gè)過程中,按鈕的點(diǎn)擊事件會(huì)多次綁定到vm上称勋。當(dāng)綁定了幾次之后胸哥,再點(diǎn)擊按鈕的時(shí)候,就會(huì)連續(xù)發(fā)出好幾個(gè)點(diǎn)擊事件
// 設(shè)置表單數(shù)據(jù)赡鲜,以及表單中事件綁定
func setSubmitForm(loginFields: [XYJMobilSuanhuaLoginField]) {
self.loginView.logFieldDatas = loginFields
// 設(shè)置手機(jī)號(hào)碼
loginFields.forEach({ (loginField) in
if loginField.name == "phoneNo" {
self.vm.phoneNo.value = loginField.value ?? ""
}
})
self.btnTapbind()
self.countdown()
// 確定登錄類型后再進(jìn)行按鈕高亮處理
self.vm.authenBtnBind()
self.formFieldbind()
// 提交按鈕高亮綁定(要在 authenBtnBind()后空厌,再設(shè)置)
self.vm.authenBtnEnable?.asObservable().bind(to: self.loginView.submitBtn.rx.enabled).disposed(by: self.vm.disposeBag!)
self.loginView.submitBtn.rx.tap.bind(to: self.vm.authenBtnTap!).disposed(by: self.vm.disposeBag!)
self.vm.authenTapResult?.subscribe(onNext: { (formResult) in
let result = self.detailForm(result: formResult)
if result.0 {
self.submitform(parameters: result.1)
}
}).disposed(by: self.vm.disposeBag!)
}
改進(jìn):
在按鈕創(chuàng)建,按鈕點(diǎn)擊事件綁定前银酬,先把前一次綁定的資源釋放
// 代碼如下
// 設(shè)置表單數(shù)據(jù)嘲更,以及表單中事件綁定
func setSubmitForm(loginFields: [XYJMobilSuanhuaLoginField]) {
self.loginView.logFieldDatas = loginFields
// 設(shè)置手機(jī)號(hào)碼
loginFields.forEach({ (loginField) in
if loginField.name == "phoneNo" {
self.vm.phoneNo.value = loginField.value ?? ""
}
})
self.btnTapbind()
self.countdown()
// 確定登錄類型后再進(jìn)行按鈕高亮處理
self.vm.authenBtnBind()
self.formFieldbind()
// 資源釋放變量也重新創(chuàng)建
self.vm.disposeBag = DisposeBag()
// 提交按鈕高亮綁定(要在 authenBtnBind()后,再設(shè)置)
self.vm.authenBtnEnable?.asObservable().bind(to: self.loginView.submitBtn.rx.enabled).disposed(by: self.vm.disposeBag!)
self.loginView.submitBtn.rx.tap.bind(to: self.vm.authenBtnTap!).disposed(by: self.vm.disposeBag!)
self.vm.authenTapResult?.subscribe(onNext: { (formResult) in
let result = self.detailForm(result: formResult)
if result.0 {
self.submitform(parameters: result.1)
}
}).disposed(by: self.vm.disposeBag!)
}