DiffableWithReload
自动调用 reloadItems(_:) 操作以对 diffable 数据源进行重新加载
新的(iOS 13+)diffable 数据源是一个很大的进步,使得 UITableView 和 UICollectionView 的使用更加容易。但有一个操作除外:项目重新加载。
为什么
现代应用程序架构将数据存储在某种 ViewModel 或 ViewStore(组合式架构、Combine Feedback 以及许多其他架构)中,而 UI 只观察数据。
很可能,ViewModel/ViewStore
- 存储要显示在表格/集合视图中的数据,这些数据通常会被转换或增强(此数据通常为 ViewModel/ViewStore 的私有数据)
- 有一个部分标识符数组
- 和一个项目标识符字典(部分标识符是键)
由于 diffable 数据源 UITableViewDiffableDataSource 和 UICollectionViewDiffableDataSource 的存在,动画更新表格/集合视图变得非常容易
- 创建新的 快照
- 设置 部分标识符
- 设置 项目标识符
- 在快照上调用 reloadItems(_:)
唯一让人生困难的步骤是最后一步:哪些项目需要重新加载?
DiffableWithReload 自动识别需要重新加载的项目,因此您无需关心重新加载。需要重新加载的单元格(仅这些)在应用快照时将自动重新加载。
类
DiffableWithReload 继承自 UITableViewDiffableDataSource 和 UICollectionViewDiffableDataSource(仍然作为通用类),因此您可以用它们与您的数据类型一起使用。
对于基本使用,有以下可用的
TableViewDiffableReloadingDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable, EquatableCellContent: Equatable>
CollectionViewDiffableReloadingDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable, EquatableCellContent: Equatable>
对于高级使用,当您需要(例如)数据锁定时,有以下子类可供使用
TableViewDiffableDelegatingDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable, Delegate: ReloadingDataSourceDelegate, EquatableCellContent: Equatable>
CollectionViewDiffableDelegatingDataSource<SectionIdentifierType: Hashable, ItemIdentifierType: Hashable, Delegate: ReloadingDataSourceDelegate, EquatableCellContent: Equatable>
示例
// change data in the cars array
cars.changeColorOfAllCars(brand: .volkswagen)
// apply the current snapshot
let snapshot = diffableDataSource.snapshot()
// items for reload are automatically created
diffableDataSource.applyWithItemsReloadIfNeeded(snapshot, animatingDifferences: true)
强烈建议您查看示例代码。示例 iOS 应用程序中有 3 个标签页
- 第一个标签页(汽车):一个基本示例,您可以在 100 行代码中看到它是如何工作的
- 第二个标签页(汽车和摩托车):接近真实世界的示例,使用视图模型和 Combine 进行更改观察。
- 第三个标签页(摩托车):展示了与集合视图一起使用,并使用更多的单元格重用标识符。
内部结构(工作原理)
- 对于每个在表格/集合视图中使用的单元格都将存储显示的内容
- 显示的内容是泛型类型
EquatableCellContent
(遵守Equatable
) - 当应用快照时,当前显示的单元格内容将与当前数据源内容进行比较,如果不相等,单元格将重新加载
- DiffableWithReload 临时存储表格/集合视图中每个使用的单元格的显示单元格内容(
EquatableCellContent
)。再次提醒,它可以是任何遵守Equatable
的类型,但有两个方便的结构会创建可比较的内容 EncodableContent
从指定的属性创建Data?
值:Data?
是显示内容的唯一标识符,可以从任何底层数据的Encodable
属性中轻松创建。提供的data
值是可选的,因为encode(to:)
可能会抛出错误。在这种情况下,单元格总是会重新加载。HashableContent
从指定的属性中创建Int
(哈希值):hashValue
不是那么独特的显示内容的标识符,然而可能足够好。默认选择应该是EncodableContent
。
设置说明
CocoaPods
要使用CocoaPods将Toast-Swift集成到您的Xcode项目中,请在您的Podfile
中指定它。
pod 'DiffableWithReload', '~> 1.0.0'
在您的代码中使用import DiffableWithReload
。
Swift Package Manager
当使用Xcode 11或更高版本时,您可以通过前往项目设置 > 《Swift Packages》来安装DiffableWithReload
,通过提供GitHub URL来添加库。或者,您也可以通过前往《文件》 > 《Swift Packages》 > 《添加包依赖...
兼容性
- 版本
1.0.0
需要Swift 5 - 示例项目使用了多个尾随闭包并且需要Swift 5.3