表格和集合视图数据源
特性
- 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
}
- 将实际数据定义为自定义数据的 observable 序列,并将其绑定到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,然后按照说明操作。