如何使用 diffable UITableView 更新表格单元格 [英] How to update a table cell using diffable UITableView

查看:23
本文介绍了如何使用 diffable UITableView 更新表格单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 UITableView 中使用了新的 NSDiffableDataSourceSnapshot 和 UITableViewDiffableDataSource.我在构建表格时没有问题,但是当单元格中显示的数据发生变化时,我在更新单元格时遇到问题.我还没有找到任何解释如何执行此操作的 Apple 文档.我尝试了以下方法:

I'm using the new NSDiffableDataSourceSnapshot and UITableViewDiffableDataSource with a UITableView. I'm having no problems building the table but I'm having problems updating a cell when the data shown in it changes. I haven't found any Apple documentation explaining how to do this. I've tried the following:

self.currentSnapshot.reloadItems([Item(identifier: identifier)])
self.dataSource.apply(self.currentSnapshot)

我在 reloadItems 中收到以下错误:

I get the following error in reloadItems:

断言失败 -[__UIDiffableDataSourceSnapshot_reloadViewUpdatesForDiffUpdate:dataSource:ignoreInvalidItems:]

Assertion failure in -[__UIDiffableDataSourceSnapshot _reloadViewUpdatesForDiffUpdate:dataSource:ignoreInvalidItems:]

我已检查传递给 Item 初始值设定项的标识符是否已存在于快照中.

I have checked that the identifier passed to the Item initializer already exists in the snapshot.

这是我的项目类:

class Item: Hashable, Equatable {

    let identifier: String
    var matchWrapper: MatchWrapper

    init(matchWrapper: MatchWrapper) {
        self.identifier = matchWrapper.identifier
        self.matchWrapper = matchWrapper
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(self.identifier)
    }

    static func == (lhs: ScoresViewController.Item, rhs: ScoresViewController.Item) -> Bool {
        return lhs.identifier == rhs.identifier
    }
}

有什么建议吗?

推荐答案

我遇到了类似的问题,经过大量调试和尝试不同的东西后,我得出的结论是我认为您不应该使用reloadItems.reloadItems 从我的测试中实际上似乎没有做任何事情.单元提供程序始终提供旧数据,如果您有一个基于标识符的散列函数和一个可检查标识符以外的事物是否相等的可等式函数,则会出现错误.

I have had similar problems and after a lot of debugging and trying out different things I've come to the conclusion that I don't think you should be using reloadItems. reloadItems doesn't actually seem to do anything from my testing. The cell provider always provides the old data and if you have a hash function based on an identifier and an equatable function that checks for equality on things other than the identifier, you get an error.

您可以尝试两件事

  1. 如果你真的想在cellProvider中使用reload items而不是使用闭包提供的数据,使用你自己的数据源作为真实来源来布置单元格.(尽管在我看来,这种方式违背了 diffableDataSource 的目的).你最终会错过 DiffableDataSource 的一些强大功能

  1. if you really want to use reload items in the cellProvider instead of using the data provided by the closure, use your own data source as the source of truth to lay out the cells. (this sort of defeats the purpose of diffableDataSource in my opinion though). You end up missing out on some of the great functionality of DiffableDataSource

而不是像这样编写代码:

instead of writing code like this:

var snapshot = tableView.snapshot()
let item = items[indexPath.row]
snapshot.reloadItems([item]) 

你可以这样做

let snapshot: NSDiffableDataSourceSnapshot<Section,Item> = .init() 
// assuming wherever you're storing your data is already updated 
snapshot.appendItems([items])
dataSource.apply(snapshot)  

这应该只刷新快照中发生更改的项目.根据我的理解,tableView 的当前快照与新创建的快照进行比较,只有不同的项目才应该更新.我在这里可能是错的,但这对我有用.

This should refresh only the items in the snapshot that have changes. From my understanding, the current snapshot of the tableView is compared with the newly created snapshot and only items that are different should be updated. I could be wrong here, but this is what has worked for me.

我看到的其他建议:

  • 编写您的哈希函数,将视图中可以更改的所有值组合在一起.
func hash(into hasher: inout Hasher) {
  hasher.combine(id)
  hasher.combine(name)
  hasher.combine(title)
}

然而,如果你走这条路线,这意味着 reloadItems 将抛出一个错误报告,指出数据源中不存在,因此你必须手动添加并删除旧数据

however if you go this route this means that reloadItems will throw an error reporting that this doesn't exist in the data source so you'll have to add this and delete the old data manually

这篇关于如何使用 diffable UITableView 更新表格单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆