就问此时此刻还有谁?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