前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS开发之DiffableDataSource

iOS开发之DiffableDataSource

作者头像
YungFan
发布2020-06-08 11:10:11
1.6K0
发布2020-06-08 11:10:11
举报
文章被收录于专栏:学海无涯

在 iOS 13 中 Apple 为 UITableView 和 UICollectionView 引入了 DiffableDataSource,让开发者可以更简单高效的实现 UITableView、UICollectionView 的局部数据刷新。新的刷新的方法为 apply,通过使用 apply 方法无需计算变更的 indexPaths,也无需调用 reload,即可安全地在主线程或后台线程更新 UI, 仅需简单的将需要变更后的数据通过 NSDiffableDataSourceSnapshot 计算出来。下面以 UITableView 为例进行讲解。

实现步骤

  • 使用 DiffableDataSource 配置当前 UITableView 的数据源。
代码语言:javascript
复制
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。
代码语言:javascript
复制
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 协议。
代码语言:javascript
复制
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 的方式也和之前不一样。
代码语言:javascript
复制
extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let city = dataSource.itemIdentifier(for: indexPath) {
            print("选择了\(city.name)")
        }
    }
}

源代码

前面介绍的是 UITableView 的关键使用步骤,UIColletionView 使用类似,完整案例详见下面的链接:

  1. UITableView案例
  2. UICollectionView案例
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现步骤
  • 源代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档