一起养成写作习惯!这是我参与「日新方案 4 月更文应战」的第25天,点击检查活动概况。
- 本文首要介绍
下RxDataSources
关于RxSwift 也有很多拓宽,咱们比较常用的便是RxCocoa
,关于Tableview
或者collectionView
也有封装,里面还有其他的拓宽,感兴趣的能够看看 RxSwiftCommunity)

1. RxCocoa
咱们正常写的话便是初始化,签订署理,完成署理。

那么运用RxCocoa怎么完成呢?咱们展现的话
let items = Observable.just([
"First Item",
"Second Item",
"Third Item"
])
items
.bind(to: tableView.rx.items) { (tableView, row, element) in
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")!
cell.textLabel?.text = "\(element) @ row \(row)"
return cell
}
.disposed(by: disposeBag)

不需求签订协议,直接绑定到咱们的tableview上,这儿咱们也能够自己注册cell
tableView.rx.items
items
.bind(to: tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (row, element, cell) in
cell.textLabel?.text = "\(element) @ row \(row)"
}
.disposed(by: disposeBag)
关于咱们tableView的一些署理事情也进行了封装
//点击事情
tableView.rx.itemSelected
.subscribe { indexPath in
print("点击了\(indexPath.element!.row)")
}.disposed(by: disposeBag)

但是咱们关于有的比如返回tableView的行高级,就没有封装,咱们这时候能够设置delegate
来完成
tableView.rx.setDelegate(self)
.disposed(by: disposeBag)
咱们完成详细署理

关于一些杂乱的分组等,咱们能够运用 RxDataSources
2. RxDataSources
咱们先看下简略的分组运用首要咱们看下sectionModel

当然咱们也能够自己自定义
struct MySection {
var header: String
var items: [Item]
}
extension MySection : AnimatableSectionModelType {
typealias Item = Int
var identity: String {
return header
}
init(original: MySection, items: [Item]) {
self = original
self.items = items
}
}
咱们创立datasource
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
let dataSource1 = RxTableViewSectionedAnimatedDataSource<MySection>(
configureCell: { ds, tv, _, item in
let cell = tv.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.text = "Item \(item)"
return cell
},
titleForHeaderInSection: { ds, index in
return ds.sectionModels[index].header
}
)
self.dataSource = dataSource1
let sections = [
MySection(header: "First section", items: [
1,
2
]),
MySection(header: "Second section", items: [
3,
4
])
]
Observable.just(sections)
.bind(to: tableView.rx.items(dataSource: dataSource1))
.disposed(by: disposeBag)
运转作用

- 不同数据源的分组
enum MultipleSectionModel {
case ImageProvidableSection(title: String, items: [SectionItem])
case ToggleableSection(title: String, items: [SectionItem])
case StepperableSection(title: String, items: [SectionItem])
}
enum SectionItem {
case ImageSectionItem(image: UIImage, title: String)
case ToggleableSectionItem(title: String, enabled: Bool)
case StepperSectionItem(title: String)
}
extension MultipleSectionModel: SectionModelType {
typealias Item = SectionItem
var items: [SectionItem] {
switch self {
case .ImageProvidableSection(title: _, items: let items):
return items.map { $0 }
case .StepperableSection(title: _, items: let items):
return items.map { $0 }
case .ToggleableSection(title: _, items: let items):
return items.map { $0 }
}
}
init(original: MultipleSectionModel, items: [Item]) {
switch original {
case let .ImageProvidableSection(title: title, items: _):
self = .ImageProvidableSection(title: title, items: items)
case let .StepperableSection(title, _):
self = .StepperableSection(title: title, items: items)
case let .ToggleableSection(title, _):
self = .ToggleableSection(title: title, items: items)
}
}
}
这儿运用枚举展现定义不同的cell款式,和Item。咱们处理数据dataSource
static func dataSource() -> RxTableViewSectionedReloadDataSource<MultipleSectionModel> {
return RxTableViewSectionedReloadDataSource<MultipleSectionModel>(
configureCell: { dataSource, table, idxPath, _ in
switch dataSource[idxPath] {
case let .ImageSectionItem(image, title):
let cell: ImageTitleTableViewCell = table.dequeueReusableCell(forIndexPath: idxPath)
cell.configure(image: image, title: title)
return cell
case let .StepperSectionItem(title):
let cell: TitleSteperTableViewCell = table.dequeueReusableCell(forIndexPath: idxPath)
cell.configure(title: title)
return cell
case let .ToggleableSectionItem(title, enabled):
let cell: TitleSwitchTableViewCell = table.dequeueReusableCell(forIndexPath: idxPath)
cell.configure(title: title, isEnabled: enabled)
return cell
}
},
titleForHeaderInSection: { dataSource, index in
let section = dataSource[index]
return section.title
}
)
}
}
咱们tableView绑定咱们datasource
let sections: [MultipleSectionModel] = [
.ImageProvidableSection(title: "Section 1",
items: [.ImageSectionItem(image: UIImage(named: "settings")!, title: "General")]),
.ToggleableSection(title: "Section 2",
items: [.ToggleableSectionItem(title: "On", enabled: true),.ToggleableSectionItem(title: "Off", enabled: false)]),
.StepperableSection(title: "Section 3",
items: [.StepperSectionItem(title: "1"),.StepperSectionItem(title: "2"),.ToggleableSectionItem(title: "On", enabled: true)])
]
let dataSource = ViewController.dataSource()
Observable.just(sections)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
运转作用

3. 对MJ封装
咱们通常也会对上拉改写和下拉加载更多进行分装,把咱们改写的事情转换为序列,并供给绑定。
extension Reactive where Base: UITableView {
/// 改写
var refresh: ControlEvent<RefreshType> {
let source = Observable<RefreshType>.create { observer in
if base.mj_header == nil {
base.mj_header = MJRefreshNormalHeader(refreshingBlock: {
observer.on(.next(.refresh))
})
}
if base.mj_footer == nil {
base.mj_footer = MJRefreshAutoNormalFooter(refreshingBlock: {
observer.on(.next(.loadMore))
})
}
return Disposables.create()
}
return ControlEvent(events: source)
}
/// 停止下拉改写
var endRefresh: Binder<(RefreshType, Bool)> {
Binder(base) { control, data in
switch data.0 {
case .refresh:
control.mj_header?.endRefreshing()
if data.1 {
control.mj_footer?.endRefreshingWithNoMoreData()
} else {
control.mj_footer?.resetNoMoreData()
}
case .loadMore:
control.mj_footer?.endRefreshing()
if data.1 {
control.mj_footer?.endRefreshingWithNoMoreData()
}
default:
if data.1 {
control.mj_footer?.endRefreshingWithNoMoreData()
}
}
}
}
}
其中RefreshType咱们定义为改写类型
enum RefreshType {
case none
case refresh
case loadMore
}
4. 总结
关于一些简略的展现类的cell比较合适,但是关于一些负责的tableView,拓宽性不是很好,比如cell高度的设定,当然咱们自己也能够拓宽。看自己需求,灵活运用。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。