Swift中UITableViewDiffableDataSource的使用

swift,uitableviewdiffabledatasource,使用 · 浏览次数 : 9

小编点评

**iOS 13 中的 DiffableDataSource 用于高效的 UITableView 和 UICollectionView 数据刷新** **步骤 1:创建 DiffableDataSource** ```swift private var dataSource: UITableViewDiffableDataSource<Section, Note>! ``` * `dataSource` 是一个 `UITableViewDiffableDataSource` 对象,它将用于存储和更新数据源中的 `Note` 结构。 **步骤 2:生成数据变化快照** ```swift var snapshot = NSDiffableDataSourceSnapshot<Section, Note>() snapshot.appendSections([.today]) snapshot.appendItems(noteList) ``` * `snapshot` 存储了 `Note` 结构的版本序列,即数据变化的描述。 * `appendSections` 方法添加了 `.today` 组,这表示将应用于 `UITableView` 的数据源。 * `appendItems` 方法添加了 `noteList` 中的 `Note` 结构,这将应用于 `UICollectionView` 的数据源。 **步骤 3:应用数据变化快照** ```swift self.dataSource.apply(snapshot, animatingDifferences: false, completion: nil) ``` * `apply` 方法使用 `snapshot` 对数据源进行差异化比对。 * `animatingDifferences: false` 参数表示不使用动画进行数据更新。 * `completion` 参数表示更新完成的回调函数,在这里调用 `updateData` 方法。 **`updateData` 方法的实现** ```swift func updateData(_ noteList: [Note]) { var snapshot = NSDiffableDataSourceSnapshot<Section, Note>() snapshot.appendSections([.today]) snapshot.appendItems(noteList) self.dataSource.apply(snapshot, animatingDifferences: false, completion: nil) } ``` * `updateData` 方法创建一个新的 `snapshot`,并将其添加到 `dataSource` 中。 * `animatingDifferences: false` 参数表示不使用动画进行数据更新。 * `completion` 参数表示更新完成的回调函数,在这里调用 `updateData` 方法。 **注意:** * `diffableDataSource` 使用了 `apply` 方法进行数据更新,这确保数据更新在主线程中进行。 * `diffableDataSource` 允许设置 `animationDuration` 和 `animationOptions` 参数来控制数据更新的动画。

正文

在 iOS 13 中 Apple 为 UITableView 和 UICollectionView 引入了 DiffableDataSource,
让开发者可以更简单高效的实现 UITableView、UICollectionView 的局部数据刷新。

新的刷新的方法为 apply
通过使用 apply 方法无需计算变更的 indexPaths,也无需调用 reload,即可安全地在主线程或后台线程更新 UI,
仅需简单的将需要变更后的数据通过 NSDiffableDataSourceSnapshot 计算出来。

主要步骤分2步
1.生成dataSource数据源:var dataSource: UITableViewDiffableDataSource<Section, Note>!
2.根据数据源修改生成变化快照:var snapshot = NSDiffableDataSourceSnapshot<Section, Note>()
3.将dataSource数据源apply应用变更快照,局部刷新UITableView
 
代码举例如下:
import UIKit
 
enum Section {
    case today
}
 
struct Note : Hashable {
    var idx : Int
    var content : String
}
 
class ViewController: UIViewController {
 
    private var dataSource: UITableViewDiffableDataSource<Section, Note>!
    
    private lazy var tableView: UITableView = {
        let tableView = UITableView()
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: String(describing: UITableViewCell.self))
        
        self.view.addSubview(tableView)
        
        return tableView
    }()
    
    override func loadView() {
        super.loadView()
        
        self.tableView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
        self.tableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        self.tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
        self.tableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
    }
 
    override func viewDidLoad() {
        super.viewDidLoad()
        let noteList = [
          Note(idx:0, content:"0"),
          Note(idx:1, content:"1"),
          Note(idx:2, content:"2"),
          Note(idx:3, content:"4")
        ]
      
        self.dataSource = getDataSource()
        updateData(noteList)
        
    }
    //1.使用 DiffableDataSource 配置当前 UITableView 的数据源, 生成UITableViewDiffableDataSource数据源
    func getDataSource() -> UITableViewDiffableDataSource<Section, Note>? {
        return UITableViewDiffableDataSource(tableView: self.tableView) { (tableView, indexPath, note) -> UITableViewCell? in
            let cell = UITableViewCell()
            cell.textLabel?.text = note.content
            return cell
        }
    }
    
    //2.使用snapshot对dataSource进行差异化比对,进行动态更新。避免了之前的复杂的维护过程
    func updateData(_ noteList: [Note]) {
        var snapshot = NSDiffableDataSourceSnapshot<Section, Note>()
        snapshot.appendSections([.today])
        snapshot.appendItems(noteList)
        //3.使用修改后的新数据snapshot,传入apply方法内,让新旧数据进行对比,然后在内部对变更后的差异数据源进行更新。
        //DiffableDataSource 通过调用自身 apply 方法将 DataSourceSnapshot 变更后的数据更新同步到 UITableView。
        self.dataSource.apply(snapshot, animatingDifferences: false, completion: nil)
    }
}

 

 

参考文章:
https://blog.csdn.net/Landen2011/article/details/125603728

 

 

与Swift中UITableViewDiffableDataSource的使用相似的内容:

Swift中UITableViewDiffableDataSource的使用

在 iOS 13 中 Apple 为 UITableView 和 UICollectionView 引入了 DiffableDataSource, 让开发者可以更简单高效的实现 UITableView、UICollectionView 的局部数据刷新。 新的刷新的方法为 apply 通过使用 app

Swift中发布-订阅框架Combine的使用

Combine简介 Combine是一个苹果用来处理事件的新的响应式框架,支持iOS 13及以上版本。 你可以使用Combine去统一和简化在处理类似于target-action,delegate,kvo等事情的代码。 iOS目前已经有第三方的响应式框架了,如:RxSwift、ReactiveCoc

Swift中常见的String用法,Array高阶使用,Set集合操作

String字符串常见用法 生成字符串 创建字符串 let greeting = "Hello, world!" let name = String("John") 连接字符串:使用加号(+)或者字符串插值(使用())来将多个字符串连接起来。 var firstName = "John" let l

Swift中指针UnsafePointer的常见用法

指针类型 //基本指针 UnsafePointer const T * UnsafeMutablePointer T * //集合指针 UnsafeBufferPointer const T * //指向一个连续已知类型区域,可以看成一个集合,并支持集合操作 UnsafeMutableBuff

Swift与OC混编

Swift调OC 在Swift项目中调用OC类中的方法需要有个{targetName}-Bridging-Header.h文件,在这个文件中导入OC要暴露给Swift的类。 {targetName}-Bridging-Header.h文件的创建有2种方式 1.自己手动创建,然后在配置文件的Objec

modulemap的使用方法

modulemap的作用 modulemap 文件是用来解决 C,Object-C,C++ 代码在 Swift 项目中集成的问题的。 在 Swift 项目中,如果需要使用 C,Object-C 或者 C++ 代码,需要将相应的头文件和源文件导入到项目中,并且需要手动管理它们之间的依赖关系。导致项目结

Swift开发基础06-闭包

Swift的闭包(Closures)是一种将功能块和上下文整合并演示在代码中的一种手段。闭包可以捕获并存储其上下文中的变量和常量。与普遍存在于其他语言的匿名函数(如Python的lambda、JavaScript的函数表达式)类似,Swift的闭包提供了强大的功能,并在很多场景中替代了函数。 闭包有

Swift之struct二进制大小分析

随着Swift的日渐成熟和给开发过程带来的便利性及安全性,京喜App中的原生业务模块和基础模块使用Swift开发占比逐渐增高。本次讨论的是struct对比Class的一些优劣势,重点分析对包体积带来的影响及规避措施。

Swift下Data处理全流程:从网络下载,数模转换,本地缓存到页面使用

Swift下将网络返回json数据转换成struct 假如网络请求返回的数据结构是一个深层嵌套的Json 首先要通过key-value取出这个json中的数据源 // 将返回的json字符串转Dictory let json = """ { "name": "jack", "age": 20, "d

Swift函数调用方式浅析

函数的调用机制 函数的调用机制是在函数调用时通过那种路径走到最终调用函数地址的机制。 在编程语言中,函数的调用机制有三种 1.静态调用:编译期就确定了函数内存地址,执行效率最高,还可以使用编译器优化如:inline函数内联提升执行效率。缺点:因为函数调用的内存地址在编译期已经确定,则无法支持继承等动