当前位置: 首页 > news >正文

UiKit中使用DiffableDataSource进行数据差异化更新

文章目录

  • 一、前言
  • 二、示例代码

一、前言

在使用UICollectionView的过程中,使用DiffableDataSource进行差异化数据更新,可以更好的优化性能,并且简化数据更新时候的动画效果。但是代码有一点问题,是关于并发的问题时候使用了nonisolated进行解决,暂时不知道更好的方式

二、示例代码

import UIKit// MARK: - 类型定义(确保在任何类之外定义)
enum HorizontalSection: String, Hashable, Sendable {case main
}// 定义数据模型,需要遵循 Hashable 和 Sendable
nonisolated struct HorizontalItem: Hashable, Sendable {let id: UUID = UUID()let title: Stringinit(title: String) {self.title = title}
}class HorizontalScrollCollectionView: UIView {// MARK: - Propertiesprivate var collectionView: UICollectionView!// ✅ 使用 lazy var 方式定义 DiffableDataSource(推荐方式)private var diffableDataSource: UICollectionViewDiffableDataSource<HorizontalSection, HorizontalItem>!var clickItemCall: ((Int) -> Void)?// ✅ Cell Registration - 使用现代化的注册方式private let cellRegistration: UICollectionView.CellRegistration<ColorCell, HorizontalItem> = {UICollectionView.CellRegistration<ColorCell, HorizontalItem> { cell, indexPath, item incell.configure(with: indexPath.item)}}()// MARK: - Initializationoverride init(frame: CGRect) {super.init(frame: frame)setupCollectionView()loadData()}required init?(coder: NSCoder) {super.init(coder: coder)setupCollectionView()loadData()}private func setupCollectionView() {let layout = UICollectionViewFlowLayout()layout.scrollDirection = .horizontallayout.minimumLineSpacing = 26layout.minimumInteritemSpacing = 10layout.itemSize = CGSize(width: 100, height: 150)collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)collectionView.translatesAutoresizingMaskIntoConstraints = falsecollectionView.backgroundColor = .clearcollectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]collectionView.showsHorizontalScrollIndicator = falsecollectionView.decelerationRate = .fastcollectionView.delegate = selfaddSubview(collectionView)NSLayoutConstraint.activate([collectionView.topAnchor.constraint(equalTo: topAnchor),collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),collectionView.bottomAnchor.constraint(equalTo: bottomAnchor)])// ✅ collectionView 已经存在,可以安全创建 diffableDataSourcediffableDataSource = UICollectionViewDiffableDataSource<HorizontalSection, HorizontalItem>(collectionView: collectionView) { [weak self] collectionView, indexPath, item inguard let self = self else { return UICollectionViewCell() }return collectionView.dequeueConfiguredReusableCell(using: self.cellRegistration,for: indexPath,item: item)}}// MARK: - Data Loadingprivate func loadData() {var items: [HorizontalItem] = []for index in 0..<10 {items.append(HorizontalItem(title: "this is item \(index)"))}// ✅ 使用 Snapshot 更新数据applySnapshot(items: items, animatingDifferences: false)}// MARK: - Apply Snapshot/// 应用快照更新数据/// - Parameters:///   - items: 要显示的数据项///   - animatingDifferences: 是否使用动画private func applySnapshot(items: [HorizontalItem], animatingDifferences: Bool = true) {var snapshot = NSDiffableDataSourceSnapshot<HorizontalSection, HorizontalItem>()snapshot.appendSections([HorizontalSection.main])snapshot.appendItems(items, toSection: HorizontalSection.main)diffableDataSource.apply(snapshot, animatingDifferences: animatingDifferences)}// MARK: - Public Methods/// 更新数据的公共方法func updateItems(_ newItems: [HorizontalItem], animated: Bool = true) {applySnapshot(items: newItems, animatingDifferences: animated)}/// 添加单个项目func addItem(_ item: HorizontalItem, animated: Bool = true) {var snapshot = diffableDataSource.snapshot()snapshot.appendItems([item], toSection: HorizontalSection.main)diffableDataSource.apply(snapshot, animatingDifferences: animated)}/// 删除指定项目func removeItem(_ item: HorizontalItem, animated: Bool = true) {var snapshot = diffableDataSource.snapshot()snapshot.deleteItems([item])diffableDataSource.apply(snapshot, animatingDifferences: animated)}/// 移动项目位置func moveItem(_ item: HorizontalItem, to destinationItem: HorizontalItem, animated: Bool = true) {var snapshot = diffableDataSource.snapshot()snapshot.moveItem(item, afterItem: destinationItem)diffableDataSource.apply(snapshot, animatingDifferences: animated)}/// 获取当前所有项目func getAllItems() -> [HorizontalItem] {return diffableDataSource.snapshot().itemIdentifiers}/// 获取指定 indexPath 的项目func getItem(at indexPath: IndexPath) -> HorizontalItem? {return diffableDataSource.itemIdentifier(for: indexPath)}
}// MARK: - UICollectionViewDelegate
extension HorizontalScrollCollectionView: UICollectionViewDelegate {func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {print("选中了第 \(indexPath.item) 个 item")// ✅ 通过 diffableDataSource 获取对应的 itemif let item = diffableDataSource.itemIdentifier(for: indexPath) {print("选中的 item 标题: \(item.title)")print("选中的 item ID: \(item.id)")}clickItemCall?(indexPath.item)}
}// MARK: - 使用示例
/*使用方式:// 1. 创建视图let horizontalView = HorizontalScrollCollectionView()view.addSubview(horizontalView)// 2. 设置点击回调horizontalView.clickItemCall = { index inprint("点击了第 \(index) 个项目")}// 3. 更新数据let newItems = [HorizontalItem(title: "新项目 1"),HorizontalItem(title: "新项目 2"),HorizontalItem(title: "新项目 3")]horizontalView.updateItems(newItems, animated: true)// 4. 添加单个项目let newItem = HorizontalItem(title: "新增项目")horizontalView.addItem(newItem, animated: true)// 5. 删除项目if let itemToRemove = horizontalView.getItem(at: IndexPath(item: 0, section: 0)) {horizontalView.removeItem(itemToRemove, animated: true)}*/
http://www.dtcms.com/a/466630.html

相关文章:

  • Elegant Query
  • 中小企业网站建设信息小企业想做网站推广找哪家强
  • 4A 架构之业务架构、数据架构、应用架构和技术架构
  • FOC电机控制原理
  • linux网络服务+linux数据库7
  • 阿里去可以做几个网站一线设计公司
  • 怎么面试一个网站开发的人wordpress 标签seo插件
  • 跨服务器快速传输数据
  • 一人AI自动化开发体系(Cursor 驱动):从需求到上线的全流程闭环与实战清单
  • Google 智能体设计模式:记忆管理
  • 大兴企业官网网站建设报价网站推荐界面
  • 精准核酸检测
  • 摩尔信使MThings入门教程3
  • 电子商务与网站建设报告福建建设工程信息网
  • 银座商城官网镇江seo网站优化
  • 网站建设好公司好做cps的网络文学网站
  • 廊坊做网站公司排名四川省住房和建设厅官方网站
  • 17.链路聚合——LACP模式(2025年10月10日)
  • PG数据文件位置迁移
  • 优化百度网站企业vi设计策划书
  • 建设一个网站平台需要哪些技术员网站到期时间查询
  • 网站建设在哪块做wordpress主题激活
  • 网站开发建设中上海网站排名优化优化
  • 做外卖在哪个网站做好兰州专业网站建设团队
  • 雄安做网站要多少钱网页建站专业公司
  • 微分中值定理(费马、罗尔、拉格朗日、柯西)
  • Umi-OCR_文字识别工具 免安装使用教程(附下载安装包)!开源离线OCR识别软件下载
  • 怎么做提升网站转化率深圳住房城乡建设局网站首页
  • 网站备案前置审批表网站建设域名的选取有讲究
  • 传统室分与数字室分系统对比