iOS开发之DiffableDataSource
2020-06-06 本文已影响0人
YungFan
在 iOS 13 中 Apple 为 UITableView 和 UICollectionView 引入了 DiffableDataSource,让开发者可以更简单高效的实现 UITableView、UICollectionView 的局部数据刷新。新的刷新的方法为 apply,通过使用 apply 方法无需计算变更的 indexPaths,也无需调用 reload,即可安全地在主线程或后台线程更新 UI, 仅需简单的将需要变更后的数据通过 NSDiffableDataSourceSnapshot 计算出来。下面以 UITableView 为例进行讲解。
实现步骤
- 使用 DiffableDataSource 配置当前 UITableView 的数据源。
var dataSource: UITableViewDiffableDataSource<Section, City>!
override func viewDidLoad() {
super.viewDidLoad()
dataSource = UITableViewDiffableDataSource
<Section, City>(tableView: tableView) {
(tableView: UITableView, indexPath: IndexPath,
city: City) -> UITableViewCell? in
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = city.name
return cell
}
dataSource.defaultRowAnimation = .fade
}
- 在需要刷新的时候,使用 DataSourceSnapshot 处理变更后的数据源,其有 append、delete、move、insert 等方法。DiffableDataSource 通过调用自身 apply 方法将 DataSourceSnapshot 变更后的数据更新同步到 UITableView。
enum Section: CaseIterable {
case main
}
var snapshot = NSDiffableDataSourceSnapshot<Section, City>()
snapshot.appendSections([.main])
snapshot.appendItems(filteredCities, toSection: .main)
dataSource.apply(snapshot, animatingDifferences: true)
- 为了确保 Diff 生效,数据源的 Model 必须具有唯一 Identifier,且遵循 Hashable 协议。
struct City: Hashable {
let name: String
let identifier = UUID()
func hash(into hasher: inout Hasher) {
hasher.combine(identifier)
}
static func ==(lhs: City, rhs: City) -> Bool {
return lhs.identifier == rhs.identifier
}
func contains(query: String?) -> Bool {
guard let query = query else { return true }
guard !query.isEmpty else { return true }
return name.contains(query)
}
}
- 点击事件中,获取 cell 的方式也和之前不一样。
extension ViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let city = dataSource.itemIdentifier(for: indexPath) {
print("选择了\(city.name)")
}
}
}
源代码
前面介绍的是 UITableView 的关键使用步骤,UIColletionView 使用类似,完整案例详见下面的链接:
我的微信公众号
定期发布 Swift、SwiftUI、Combine、iOS开发等技术文章,也会更新一些自己的学习心得,欢迎大家关注。
![](https://img.haomeiwen.com/i735757/19b77683dd50a681.jpg)