RxSwift官方实例十(刷新)
2020-12-17 本文已影响0人
酒茶白开水
搭建UI
新建控制器,搭建两个UITableView
和一个UICollectionView
作为控制器属性:
@IBOutlet weak var partialTableView: UITableView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var partialCollectionView: UICollectionView!
在控制器的viewDidLoad
函数中为导航栏的右侧设置一个item
:
// 构建UI
let rightItem = UIBarButtonItem(title: "更新", style: .plain, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightItem
数据生成
定义一个数据类型作为本示例的数据类型NumberSection
:
typealias NumberSection = SectionModel<Int, Int>
定义一个数据混乱器Randomizer
,作用就是将[NumberSection]
这样的数据打散、打乱。sections
属性存储结果数据,randomize
函数混乱数据。具体实现查看代码……
定义一个UpdatesViewModel
:
struct UpdatesViewModel {
private var generator = Randomizer(sections: [NumberSection]())
let sections: Driver<[NumberSection]>
init(update: RxCocoa.ControlEvent<()>) {
// 构建初始数据
var sectionsData = [NumberSection]()
for i in 0 ..< 10 {
sectionsData.append(NumberSection(model: i + 1, items: Array(i ..< i + 100)))
}
let generator = Randomizer(sections: sectionsData)
self.generator = generator
sections = update.map { () -> [NumberSection] in
generator.randomize()
return generator.sections
}.asDriver(onErrorJustReturn: sectionsData)
.startWith(sectionsData)
}
}
- 属性
generator
用来更新数据,sections
就是最终的数据序列 - 初始化函数中,接收一个更新数据指令的参数
update
,通过map
操作符转换为需要的数据,再使用asDriver
、startWith
操作符来避免错误以及设置初始元素
绑定数据
回到控制器定义两个懒加载属性tableViewDataSource
、collectionViewDataSource
来辅助绑定UITableView和UICollectionView:
lazy var tableViewDataSource = {
TableViewSectionedDataSource<NumberSection>(cellForRow: { (ds, tv, ip) -> UITableViewCell in
let cell = CommonCell.cellFor(tableView: tv)
cell.textLabel?.text = "\(ds[ip])"
return cell
}, titleForHeader: { (ds, tv, i) -> String? in
return "第\(ds[i].model)组"
})
}()
lazy var collectionViewDataSource = {
CollectionViewSectionedDataSource<NumberSection>(cellForItem: { [weak self] (ds, cv, ip) -> UICollectionViewCell in
let cell = TextCollectionViewCell.cellFor(collectionView: cv, indexPath: ip, identifier: self!.cellID)
cell.textLabel.text = "\(ds[ip])"
return cell
}, viewForSupplementaryElement: { [weak self] (ds, cv, kind, ip) -> UICollectionReusableView in
let view = TextCollectionReusableView.viewFor(collectionView: cv, indexPath: ip, kind: kind, identifier: self!.reusableViewID)
view.textLabel.text = "第\(ds[ip.section].model)组"
return view
})
}()
在控制器的viewDidLoad
函数中将数据绑定到前面搭建的UI元素上,方式都与之前的一样,在此不做分析:
// 绑定
let viewModel = UpdatesViewModel(update: rightItem.rx.tap)
viewModel.sections
.drive(partialTableView.rx.items(dataSource: tableViewDataSource))
.disposed(by: bag)
viewModel.sections
.drive(tableView.rx.items(dataSource: tableViewDataSource))
.disposed(by: bag)
Observable.of(tableView.rx.modelSelected(Int.self), partialTableView.rx.modelSelected(Int.self))
.merge()
.subscribe(onNext: {print("我是\($0)") })
.disposed(by: bag)
viewModel.sections
.drive(partialCollectionView.rx.items(dataSource: collectionViewDataSource))
.disposed(by: bag)
partialCollectionView.rx
.modelSelected(Int.self)
.subscribe(onNext: { print("我是\($0)") })
.disposed(by: bag)