表格和集合视图数据源
功能
- O(N) 算法用于计算差异
- 算法假定所有节和项是唯一的,所以没有歧义
- 如果存在歧义,将自动降级为非动画刷新
- 它通过对分发到分节视图的命令数量进行额外的启发式处理来发送最少的命令
- 尽管运行时间是线性的,但通常发送的命令数量远远少于线性
- 通常(并且可能)限制更改的数量在一个较小的数字,如果更改的数量接近线性增长,则执行正常的重新加载
- 支持扩展您的项和节结构
- 只需通过添加
IdentifiableType
和Equatable
扩展您的项,然后通过添加AnimatableSectionModelType
扩展您的节
- 只需通过添加
- 支持两个级别的层次动画的所有组合,适用于 节和项
- 节动画:插入、删除、移动
- 项动画:插入、删除、移动、重新加载(如果旧值不等于新值)
- 可配置
Insert
、Reload
和Delete
的动画类型(自动、淡出、...) - 示例应用
- 随机压力测试(示例应用)
- 支持开箱式编辑(示例应用)
- 适用于
UITableView
和UICollectionView
为什么
编写表格和集合视图的数据源是枯燥的。对于最简单的情况,也需要实现大量代理方法。
RxSwift通过简单的数据绑定机制舒缓了一些负担。
- 将数据转换成一个可观察的序列。
- 使用以下之一将数据绑定到tableView/collectionView
rx.items(dataSource:protocol<RxTableViewDataSourceType, UITableViewDataSource>)
rx.items(cellIdentifier:String)
rx.items(cellIdentifier:String:Cell.Type:_:)
rx.items(_:_:)
let data = Observable<[String]>.just(["first element", "second element", "third element"])
data.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { index, model, cell in
cell.textLabel?.text = model
}
.disposed(by: disposeBag)
这对于简单的数据集很有用,但不能处理需要绑定多部分复杂数据集或在进行添加/修改/删除项时需要执行动画的情况。
这正是RxDataSources帮助解决的问题。
使用RxDataSources,只要编写
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Int>>(configureCell: configureCell)
Observable.just([SectionModel(model: "title", items: [1, 2, 3])])
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
怎么做
给出以下自定义数据结构
struct CustomData {
var anInt: Int
var aString: String
var aCGPoint: CGPoint
}
- 首先使用一个遵循
SectionModelType
协议的结构定义你的部分。
- 定义
Item
别名类型:等于该部分将包含的项的类型。 - 声明一个
items
属性:为一个Item
类型的数组。
struct SectionOfCustomData {
var header: String
var items: [Item]
}
extension SectionOfCustomData: SectionModelType {
typealias Item = CustomData
init(original: SectionOfCustomData, items: [Item]) {
self = original
self.items = items
}
}
- 创建一个dataSource对象并传递你的
SectionOfCustomData
类型。
let dataSource = RxTableViewSectionedReloadDataSource<SectionOfCustomData>(
configureCell: { dataSource, tableView, indexPath, item in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Item \(item.anInt): \(item.aString) - \(item.aCGPoint.x):\(item.aCGPoint.y)"
return cell
})
- 根据需要自定义dataSource上的闭包。
titleForHeaderInSection
titleForFooterInSection
- 等等
dataSource.titleForHeaderInSection = { dataSource, index in
return dataSource.sectionModels[index].header
}
dataSource.titleForFooterInSection = { dataSource, index in
return dataSource.sectionModels[index].footer
}
dataSource.canEditRowAtIndexPath = { dataSource, indexPath in
return true
}
dataSource.canMoveRowAtIndexPath = { dataSource, indexPath in
return true
}
- 将实际数据定义为一个CustomData对象的可观察序列并将它绑定到tableView。
let sections = [
SectionOfCustomData(header: "First section", items: [CustomData(anInt: 0, aString: "zero", aCGPoint: CGPoint.zero), CustomData(anInt: 1, aString: "one", aCGPoint: CGPoint(x: 1, y: 1)) ]),
SectionOfCustomData(header: "Second section", items: [CustomData(anInt: 2, aString: "two", aCGPoint: CGPoint(x: 2, y: 2)), CustomData(anInt: 3, aString: "three", aCGPoint: CGPoint(x: 3, y: 3)) ])
]
Observable.just(sections)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
动画数据源
RxDataSources提供了两种特殊的数据源类型,它们可以自动处理绑定数据源的更改动画:RxTableViewSectionedAnimatedDataSource
和RxCollectionViewSectionedAnimatedDataSource
。
要使用这两种动画数据源之一,除了上述步骤外,还需要做几步额外的工作
- SectionOfCustomData需要符合
AnimatableSectionModelType
- 你的数据模型必须符合
IdentifiableType
:由IdentifiableType
协议提供的identity
必须是一个表示模型实例的**不可变标识符**。例如,在Car
模型的情况下,你可能希望使用车辆的plateNumber
作为其标识符。Equatable
:符合Equatable
协议有助于RxDataSources
确定哪些单元格已更改,以便只对这些特定的单元格进行动画处理。也就是说,更改Car
模型属性中的任何一个都将触发该单元格的动画重载。
需求
Xcode 10.2
Swift 5.0
对于 Swift 4.x 版本,请使用 3.0.0 ... 3.1.0
版本;对于 Swift 3.x 版本,请使用 1.0 ... 2.0.2
版本;对于 Swift 2.3 版本,请使用 0.1 ... 0.9
版本。
安装
我们会尽可能保持API的稳定性,但可能会出现破坏API变更。
CocoaPods
Podfile
pod 'RxDataSources', '~> 4.0'
Carthage
Cartfile
github "RxSwiftCommunity/RxDataSources" ~> 4.0
Swift 包管理器
创建一个 Package.swift
文件。
import PackageDescription
let package = Package(
name: "SampleProject",
dependencies: [
.package(url: "https://github.com/RxSwiftCommunity/RxDataSources.git", from: "4.0.0")
]
)
如果您使用的是 Xcode 11 或更高版本,请转到 文件 / Swift 包 / 添加包依赖...,并输入包仓库 URL https://github.com/RxSwiftCommunity/RxDataSources.git,然后按照说明操作。