就問此時此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!git
- RxSwift(1)— 初探
- RxSwift(2)— 核心邏輯源碼分析
- RxSwift(3)— Observable序列的建立方式
- RxSwift(4)— 高階函數(上)
- RxSwift(5)— 高階函數(下)
- RxSwift(6)— 調度者-scheduler源碼解析(上)
- RxSwift(7)— 調度者-scheduler源碼解析(下)
- RxSwift(8)— KVO底層探索(上)
- RxSwift(9)— KVO底層探索(下)
- RxSwift(10)— 場景序列總結
- RxSwift(11)— dispose源碼解析
- RxSwift(12)— Subject即攻也守
- RxSwift(13)— 爬過的坑
- RxSwift(14)— MVVM雙向綁定
RxSwift 目錄直通車 --- 和諧學習,不急不躁!github
/// tableView -- RX
func setupTableViewRX() {
let dataOB = BehaviorSubject.init(value: self.viewModel.dataArray)
// 騷起來
// dataOB.bind(to: self.tableView.rx.items){(tabView,row,model) ->LGTableViewCell in
// let cell = tabView.dequeueReusableCell(withIdentifier: resuseID) as! LGTableViewCell
// cell.setUIData(model as! LGModel)
// return cell
// }.disposed(by: disposeBag)
dataOB.asObserver().bind(to: self.tableView.rx.items(cellIdentifier: resuseID, cellType: LGTableViewCell.self)){
(row,model,cell) in
cell.setUIData(model as! LGModel)
}.disposed(by: self.disposeBag)
// tableView點擊事件
tableView.rx.itemSelected.subscribe(onNext: { [weak self](indexPath) in
print("點擊\(indexPath)行")
self?.navigationController?.pushViewController(LGSectionViewController(), animated: true)
self?.tableView.deselectRow(at: indexPath, animated: true)
}).disposed(by: self.disposeBag)
// tableView複選點擊事件
tableView.rx.itemDeselected.subscribe(onNext: { (indexPath) in
print("再次點擊\(indexPath)行")
}).disposed(by: self.disposeBag)
// tableView移動事件
tableView.rx.itemMoved.subscribe(onNext: { [weak self] (sourceIndex,destinationIndex) in
print("從\(sourceIndex)移動到\(destinationIndex)")
self?.viewModel.dataArray.swapAt(sourceIndex.row, destinationIndex.row)
self?.loadUI(obSubject: dataOB)
}).disposed(by: self.disposeBag)
// tableView刪除事件
tableView.rx.itemDeleted.subscribe(onNext: { [weak self](indexPath) in
print("點擊刪除\(indexPath)行")
self?.viewModel.dataArray.remove(at: indexPath.row)
self?.loadUI(obSubject: dataOB)
}).disposed(by: self.disposeBag)
// tableView新增事件
tableView.rx.itemInserted.subscribe(onNext: { [weak self](indexPath) in
print("添加數據在\(indexPath)行")
guard let model = self?.viewModel.dataArray.last else{
print("數據有問題,沒法新增")
return
}
self?.viewModel.dataArray.insert(model, at: indexPath.row)
self?.loadUI(obSubject: dataOB)
}).disposed(by: self.disposeBag)
}
複製代碼
TableView
的點擊、複選、新增、刪除、移動
所有簡潔實現RxSwift
一旦趕上了TableView
,根本不須要那些噁心的膠水代碼delegate & dataSource
的賦值直接免去/// Rx 處理分組
func setupTableViewRX() {
let tableViewDataSource = RxTableViewSectionedReloadDataSource<SectionModel<String,LGSectionModel>>(configureCell: { [weak self](dataSource, tab, indexPath, model) -> LGTableViewCell in
let cell = tab.dequeueReusableCell(withIdentifier: self?.resuseID ?? "resuseID_LGSectionViewController", for: indexPath) as! LGTableViewCell
cell.setUISectionData(model)
cell.selectionStyle = .none
return cell
},titleForHeaderInSection: { dataSource,index -> String in
// print("數據:\(dataSource.sectionModels[index].identity)")
return dataSource.sectionModels[index].model
})
/// 咱們上次就是經過bind函數,這裏咱們變化一下
self.data.githubData.asDriver(onErrorJustReturn: [])
.drive(self.tableView.rx.items(dataSource: tableViewDataSource))
.disposed(by: self.disposeBag)
/// 跳轉到網絡相關Demo
self.tableView.rx.itemSelected.subscribe(onNext: { [weak self](indexPath) in
self?.navigationController?.pushViewController(LGNetworkViewController(), animated: true)
}).disposed(by: self.disposeBag)
}
複製代碼
RxCocoa
封裝的dataSourcer
讓咱們爽的沒法自拔dataSource
的承擔了整個數據源代理,而且強勢封裝了代理RxSwift
讓咱們的開發更直接面向開發,讓開發更容易override func viewDidLoad() {
super.viewDidLoad()
self.setupUI()
// 如今來一個需求:咱們的輸入框搜索 - 請求網絡 - 下面tableView聯動
// UI <-> model
self.searchBar.rx.text.orEmpty
.bind(to: self.viewModel.searchTextOB)
.disposed(by: disposeBag)
// 數據層綁定UI
self.viewModel.searchData.drive(self.tableView.rx.items){ (tableView, indexPath, model) -> LGTableViewCell in
let cell = tableView.dequeueReusableCell(withIdentifier: self.resuseID) as! LGTableViewCell
cell.nameLabel.text = model.name
cell.classLabel.text = model.url
return cell
}
.disposed(by: disposeBag)
// tittle綁定
self.viewModel.searchData.map { (array) -> String in
return "搜索到了 \(array.count) 條數據"
}
.drive(self.navigationItem.rx.title)
.disposed(by: disposeBag)
// 滑動減速綁定
self.tableView.rx.didEndDecelerating
.subscribe { [weak self] in
self?.searchBar.endEditing(true)
}.disposed(by: disposeBag)
}
複製代碼
RxSwift
世界裏的ViewController
,這纔是真正的輕量化的VC
,至始至終都只作一件事:創建View與ViewModel之間的綁定依賴關係ViewModel
,讓它在它的世界裏處理業務層,網絡層數據的返回ViewModel
響應對外,達到數據綁定到UI
的效果ViewModel
裏面咱們運用RxSwift
的高階函數,處理邏輯lazy var searchData: Driver<[LGReposityModel]> = {
return self.searchTextOB.asObserver()
.throttle(RxTimeInterval.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.flatMapFirst(LGComprehensiveViewModel.resposeData)
.asDriver(onErrorJustReturn: [])
}()
複製代碼
throttle
保證了相隔0.3秒發送一次事件distinctUntilChanged
函數保證了帶寬,直到搜索字眼變更的時候才請求flatMapFirst
由於序列的序列,咱們下沉請求,回調結果asDriver
包裝成Drive
序列,保證狀態共享,主線程調度,沒有錯誤返回static func resposeData(_ githunId: String) -> Observable<[LGReposityModel]> {
guard !githunId.isEmpty,let url = URL(string: "https://api.github.com/users/\(githunId)/repos") else {
return Observable.just([])
}
return URLSession.shared.rx.json(url: url)
.retry()
.observeOn(ConcurrentDispatchQueueScheduler(qos: .background))
.map(LGComprehensiveViewModel.parseData)
}
複製代碼
URLSession.shared.rx.json
,返回jsonobserveOn
map
映射,下沉的序列化結果static func parseData(_ json: Any) -> [LGReposityModel] {
guard let items = json as? [[String: Any]] else {return []}
guard let result = [LGReposityModel].deserialize(from: items) else { return [] }
return result as! [LGReposityModel]
}
複製代碼
HandJSON
進行數據解析完美實現聯動,MVVM雙向綁定加入RxSwift的身影也就更出色json
全部的努力都會在某一個時刻兌現,咱們不少小夥伴都會感嘆怎麼還不來!你要知道:毋庸置疑,好的事情總會到來,當他來晚的時候也不失爲一種驚喜swift
就問此時此刻還有誰?45度仰望天空,該死!我這無處安放的魅力!api