gpt4 book ai didi

ios - 如何从 iOS 13 中的 NSFetchResultsController 获取可比较的快照?

转载 作者:行者123 更新时间:2023-12-01 22:18:18 27 4
gpt4 key购买 nike

所以我们在 WWDC 2019 视频 230 中,从大约第 14 分钟开始,据称 NSFetchedResultsController 现在提供了一个 NSDiffableDataSourceSnapshot,因此我们可以将其直接应用于可比较的数据源 (UITableViewDiffableDataSource)。

但这并不完全是他们所说的,或者我们得到的。我们在委托(delegate)方法controller(_:didChangeContentWith:)中得到的是一个NSDiffableDataSourceReference。我们如何从这个得到实际的快照,以及我的可区分数据源通用类型应该是什么?

最佳答案

WWDC 视频暗示我们应该使用 StringNSManagedObjectID 泛型类型声明数据源。这对我不起作用;我可以通过动画和行更新获得合理行为的唯一方法是使用自定义值对象作为数据源的行标识符。

使用 NSManagedObjectID 作为项目标识符的快照的问题在于,尽管获取的结果委托(delegate)会收到与该标识符关联的托管对象发生更改的通知,但它提供的快照可能不是与我们可能应用于数据源的前一个不同。当底层数据发生变化时,将此快照映射到使用值对象作为标识符的快照会产生不同的哈希值,并解决单元格更新问题。

考虑一个待办事项列表应用程序的数据源,其中有一个包含任务列表的 TableView 。每个单元格都会显示一个标题以及任务是否完成的一些指示。值对象可能如下所示:

struct TaskItem: Hashable {
var title: String
var isComplete: Bool
}

数据源呈现这些项目的快照:

typealias DataSource = UITableViewDiffableDataSource<String, TaskItem>

lazy var dataSource = DataSource(tableView: tableView) { tableView, indexPath, item in {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = item.title
cell.accessoryType = item.isComplete ? .checkmark : .none
return cell
}

假设获取的结果 Controller 可以分组,委托(delegate)将传递一个类型为 StringNSManagedObjectID 的快照。可以将其操作为 StringTaskItem(用作行标识符的值对象)的快照,以应用于数据源:

func controller(
_ controller: NSFetchedResultsController<NSFetchRequestResult>,
didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference
) {
// Cast the snapshot reference to a snapshot
let snapshot = snapshot as NSDiffableDataSourceSnapshot<String, NSManagedObjectID>

// Create a new snapshot with the value object as item identifier
var mySnapshot = NSDiffableDataSourceSnapshot<String, TaskItem>()

// Copy the sections from the fetched results controller's snapshot
mySnapshot.appendSections(snapshot.sectionIdentifiers)

// For each section, map the item identifiers (NSManagedObjectID) from the
// fetched result controller's snapshot to managed objects (Task) and
// then to value objects (TaskItem), before adding to the new snapshot
mySnapshot.sectionIdentifiers.forEach { section in
let itemIdentifiers = snapshot.itemIdentifiers(inSection: section)
.map {context.object(with: $0) as! Task}
.map {TaskItem(title: $0.title, isComplete: $0.isComplete)}
mySnapshot.appendItems(itemIdentifiers, toSection: section)
}

// Apply the snapshot, animating differences unless not in a window
dataSource.apply(mySnapshot, animatingDifferences: view.window != nil)
}

viewDidLoad 中的初始 performFetch 更新表格 View ,但没有动画。此后的所有更新(包括仅刷新单元格的更新)都可以使用动画。

关于ios - 如何从 iOS 13 中的 NSFetchResultsController 获取可比较的快照?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58475481/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com