搭建UI
新建控制器拗引,搭建兩個(gè)UITableView
和一個(gè)UICollectionView
作為控制器屬性:
@IBOutlet weak var partialTableView: UITableView!
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var partialCollectionView: UICollectionView!
在控制器的viewDidLoad
函數(shù)中為導(dǎo)航欄的右側(cè)設(shè)置一個(gè)item
:
// 構(gòu)建UI
let rightItem = UIBarButtonItem(title: "更新", style: .plain, target: nil, action: nil)
self.navigationItem.rightBarButtonItem = rightItem
數(shù)據(jù)生成
定義一個(gè)數(shù)據(jù)類型作為本示例的數(shù)據(jù)類型NumberSection
:
typealias NumberSection = SectionModel<Int, Int>
定義一個(gè)數(shù)據(jù)混亂器Randomizer
和措,作用就是將[NumberSection]
這樣的數(shù)據(jù)打散、打亂疤估。sections
屬性存儲結(jié)果數(shù)據(jù)凳怨,randomize
函數(shù)混亂數(shù)據(jù)。具體實(shí)現(xiàn)查看代碼……
定義一個(gè)UpdatesViewModel
:
struct UpdatesViewModel {
private var generator = Randomizer(sections: [NumberSection]())
let sections: Driver<[NumberSection]>
init(update: RxCocoa.ControlEvent<()>) {
// 構(gòu)建初始數(shù)據(jù)
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
用來更新數(shù)據(jù)绪抛,sections
就是最終的數(shù)據(jù)序列 - 初始化函數(shù)中像屋,接收一個(gè)更新數(shù)據(jù)指令的參數(shù)
update
微驶,通過map
操作符轉(zhuǎn)換為需要的數(shù)據(jù),再使用asDriver
开睡、startWith
操作符來避免錯(cuò)誤以及設(shè)置初始元素
綁定數(shù)據(jù)
回到控制器定義兩個(gè)懶加載屬性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
函數(shù)中將數(shù)據(jù)綁定到前面搭建的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)