我正在使用我的应用程序中实现搜索屏幕UITableViewDiffableDataSource
。每个单元格代表一个搜索命中,并在单元格标题中突出显示搜索匹配,有点像 Xcode 的“快速打开”窗口突出显示其结果项的部分内容。当在搜索字段中输入文本时,我会更新结果列表。随着相关性的变化,结果在列表中上下移动。
诀窍是,我需要在每次搜索文本更改时强制每个单元格重新渲染,因为新的搜索字符串意味着单元格标题的突出显示部分的更新。但我不想为删除和插入设置动画,因为它仍然是同一个项目。如何使用快照告诉数据源需要重新加载单元格?
我这样声明数据源:
@property (retain) UITableViewDiffableDataSource<NSString *, SearchHit *> *dataSource;
SearchHit
代表一个搜索结果;它具有显示标题的属性和要在标题中突出显示的范围数组。它覆盖了hash
and isEqual:
以便每个结果行都是唯一标识的。
我的代码看起来像这样:
-(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
呼叫有所帮助,但现在大多数单元格不断落后于一次更新。这听起来像是我的代码中某处的逻辑错误,但我已经验证传递到快照的命中是正确的,而传递到数据源的单元格创建回调的命中则不正确。
本文 https://www.donnywals.com/modern-table-views-with-diffable-data-sources/作者:唐尼·沃尔斯和这个相关的 Twitter 线程 https://twitter.com/lilhinx/status/1205904266847637504Steve Breen 提出解决这个问题的方法是让项目标识符类型仅表示显示单元格所需的属性。所以我更新了SearchHit
的哈希和相等比较包括标题的突出显示部分,这是他们以前没有的。然后我在每次更新时删除和插入所有单元格的动画,这是我不想要的。
这看起来像什么reloadItemsWithIdentifiers
应该做...对吗?
示例项目here https://github.com/tomhamming/DiffableOneBehind在 GitHub 上。