上一篇探索了一下tableView和RxSwift使用,如果遇到分组数据的情况,RxSwift依然有提供相关方法,比如下面例子:
let tableViewDataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, SectionModel>>(configureCell: { (dataSource, tableView, indexPath, model) -> TestTableViewCell in
let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell", for: indexPath) as! TestTableViewCell
cell.setSectionData(model)
return cell
}, titleForHeaderInSection: { (dataSource, index) -> String in
return dataSource.sectionModels[index].title
})
//绑定
dataDriver.drive(tableView.rx.items(dataSource: tableViewDataSource))
.disposed(by: disposeBag)
-
源码分析
RxTableViewSectionedReloadDataSource
继承了TableViewSectionedDataSource
,TableViewSectionedDataSource
拥有很多默认初始化的闭包,这些闭包都会在DataSource
协议里调用,从而实现在外面自定义Section
:
open class RxTableViewSectionedReloadDataSource<Section: SectionModelType>
: TableViewSectionedDataSource<Section>
, RxTableViewDataSourceType {
...
}
open class TableViewSectionedDataSource<Section: SectionModelType>
: NSObject
, UITableViewDataSource
, SectionedViewDataSourceType {
public typealias Item = Section.Item
public typealias ConfigureCell = (TableViewSectionedDataSource<Section>, UITableView, IndexPath, Item) -> UITableViewCell
public typealias TitleForHeaderInSection = (TableViewSectionedDataSource<Section>, Int) -> String?
public typealias TitleForFooterInSection = (TableViewSectionedDataSource<Section>, Int) -> String?
public typealias CanEditRowAtIndexPath = (TableViewSectionedDataSource<Section>, IndexPath) -> Bool
public typealias CanMoveRowAtIndexPath = (TableViewSectionedDataSource<Section>, IndexPath) -> Bool
#if os(iOS)
public typealias SectionIndexTitles = (TableViewSectionedDataSource<Section>) -> [String]?
public typealias SectionForSectionIndexTitle = (TableViewSectionedDataSource<Section>, _ title: String, _ index: Int) -> Int
#endif
#if os(iOS)
public init(
configureCell: @escaping ConfigureCell,
titleForHeaderInSection: @escaping TitleForHeaderInSection = { _, _ in nil },
titleForFooterInSection: @escaping TitleForFooterInSection = { _, _ in nil },
canEditRowAtIndexPath: @escaping CanEditRowAtIndexPath = { _, _ in false },
canMoveRowAtIndexPath: @escaping CanMoveRowAtIndexPath = { _, _ in false },
sectionIndexTitles: @escaping SectionIndexTitles = { _ in nil },
sectionForSectionIndexTitle: @escaping SectionForSectionIndexTitle = { _, _, index in index }
) {
self.configureCell = configureCell
self.titleForHeaderInSection = titleForHeaderInSection
self.titleForFooterInSection = titleForFooterInSection
self.canEditRowAtIndexPath = canEditRowAtIndexPath
self.canMoveRowAtIndexPath = canMoveRowAtIndexPath
self.sectionIndexTitles = sectionIndexTitles
self.sectionForSectionIndexTitle = sectionForSectionIndexTitle
}
#else
...
#endif
...
// UITableViewDataSource
open func numberOfSections(in tableView: UITableView) -> Int {
return _sectionModels.count
}
open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard _sectionModels.count > section else { return 0 }
return _sectionModels[section].items.count
}
open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
precondition(indexPath.item < _sectionModels[indexPath.section].items.count)
return configureCell(self, tableView, indexPath, self[indexPath])
}
open func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return titleForHeaderInSection(self, section)
}
open func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
return titleForFooterInSection(self, section)
}
open func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return canEditRowAtIndexPath(self, indexPath)
}
open func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return canMoveRowAtIndexPath(self, indexPath)
}
open func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
self._sectionModels.moveFromSourceIndexPath(sourceIndexPath, destinationIndexPath: destinationIndexPath)
}
#if os(iOS)
open func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sectionIndexTitles(self)
}
open func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
return sectionForSectionIndexTitle(self, title, index)
}
#endif
}