如何在不删除和插入 UITableViewDiffableDataSource 的情况下重新加载项目? [英] How can I reload items without removing and inserting with UITableViewDiffableDataSource?

查看:97
本文介绍了如何在不删除和插入 UITableViewDiffableDataSource 的情况下重新加载项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 UITableViewDiffableDataSource 在我的应用中实现一个搜索屏幕.每个单元格代表一个搜索命中并在单元格标题中突出显示搜索匹配,有点像 Xcode 的 Open Quickly 窗口突出显示其结果项的部分.在搜索字段中输入文本时,我更新了结果列表.结果随着相关性的变化在列表中上下移动.

I'm implementing a search screen in my app using UITableViewDiffableDataSource. Each cell represents a search hit and highlights the search match in the cell title, kind of like Xcode's Open Quickly window highlights portions of its result items. As text is typed into the search field, I update the results list. Results move up and down in the list as their relevance changes.

诀窍是每次搜索文本更改时我都需要强制每个单元格重新呈现,因为新的搜索字符串意味着更新单元格标题的突出显示部分.但我不想动画删除和插入,因为它仍然是同一个项目.如何使用快照告诉数据源它需要重新加载单元格?

The trick is that I need to force every cell to re-render every time the search text changes, because a new search string means an update to the highlighted portions of the cell title. But I don't want to animate a deletion and insert, because it's still the same item. How can I tell the data source using the snapshot that it needs to reload cells?

我这样声明数据源:

@property (retain) UITableViewDiffableDataSource<NSString *, SearchHit *> *dataSource;

SearchHit 代表一个搜索结果;它具有显示标题和要在标题中突出显示的范围数组的属性.并且它会覆盖 hashisEqual: 以便唯一标识每个结果行.

SearchHit represents one search result; it has properties for a display title and an array of ranges to highlight in the title. And it overrides hash and isEqual: so that every result row is uniquely identified.

我的代码如下所示:

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
  NSArray<SearchHit *> *hits = [self fetchHits:searchText];
  NSDiffableDataSourceSnapshot<NSString *, SearchHit *> *snap = [[[NSDiffableDataSourceSnapshot alloc] init] autorelease];
  [snap appendSectionsWithIdentifiers:@[@""]];
  [snap appendItemsWithIdentifiers:hits];
  [snap reloadItemsWithIdentifiers:hits];
  [self.dataSource applySnapshot:snap animatingDifferences:YES];
}

起初我没有在那里调用 reloadItemsWithIdentifiers,然后一旦它出现在结果列表中,任何单元格都不会改变.添加 reload 调用有帮助,但现在大多数单元格总是落后于一个更新.这在我的代码中有点像逻辑错误,但我已经验证传递给快照的命中是正确的,而传递给数据源的单元格创建回调的命中不是.

At first I didn't have the reloadItemsWithIdentifiers call there, and then no cell would change at all once it was in the result list. Adding the reload call helped, but now most of the cells are constantly one update behind. This smells like a logic error somewhere in my code, but I've verified that the hits passed to the snapshot are correct and the hits passed to the data source's cell creation callback are not.

本文,作者:Donny Wals 和 此相关 Twitter 线程 涉及史蒂夫·布林 (Steve Breen) 建议解决此问题的方法是仅使项目标识符类型表示显示单元格所需的属性.因此,我更新了 SearchHit 的哈希和相等比较,以包括标题的突出显示部分,而他们以前没有.然后我在每次更新时删除和插入所有单元格的动画,这是我不想要的.

This article by Donny Wals and this related Twitter thread involving Steve Breen suggests that the way to fix this is to make the item identifier type only represent the properties needed to display the cell. So I updated SearchHit's hash and equality comparison to include the highlighted portions of the title, which they didn't before. Then I got delete and insert animations for all the cells on every update, which I don't want.

这看起来是 reloadItemsWithIdentifiers 应该做的......对吗?

This seems like what reloadItemsWithIdentifiers should do...right?

示例项目 此处在 GitHub 上.

Sample project here on GitHub.

推荐答案

diffable 数据源 API 可能不是对单元格本身产生动画效果的正确工具.它面向单元格的出现、消失和排序的动画.如果您的数据源具有通过 Hashable 一致性表示的更改,则 api 会将其视为更改并删除/插入等.

The diffable datasource API may not be the right tool to effect animations on cells themselves. It’s geared towards the animation of the appearance, disappearance and ordering of cells. If your data source has a change that is expressed via Hashable conformance the api will see it as a change and delete/insert etc.

我的建议是从项目标识符中删除搜索文本,让每个单元格观察搜索文本并独立于数据源产生动画或重绘.

My advice would be to remove the search text from the item identifier and have each cell observe the search text and effect an animation or redraw independently from the datasource.

这篇关于如何在不删除和插入 UITableViewDiffableDataSource 的情况下重新加载项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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