我正在使用UITableViewDiffableDataSource在我的应用程序中实现一个搜索屏幕。每个单元格代表一个搜索匹配,并在单元格标题中突出显示搜索匹配,这有点像Xcode的快速打开窗口突出显示其结果项的部分。在搜索字段中键入文本时,我会更新结果列表。随着相关性的变化,结果会在列表中上下移动。
诀窍是,每次搜索文本更改时,我都需要强制每个单元格重新呈现,因为新的搜索字符串意味着更新单元格标题的突出显示部分。但我不想动画删除和插入,因为它仍然是相同的项目。如何告诉使用快照的数据源需要重新加载单元格?
我像这样声明数据源:
@property (retain) UITableViewDiffableDataSource<NSString *, SearchHit *> *dataSource;SearchHit表示一个搜索结果;它有一个显示标题的属性和一个要在标题中突出显示的范围数组。它覆盖了hash和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调用很有帮助,但现在大多数计算单元总是落后一个更新。这看起来像是我的代码中的某个地方出现了逻辑错误,但是我已经验证了传递给快照的命中是正确的,而传递给数据源的单元格创建回调的命中是错误的。
Donny Wals的This article和涉及Steve Breen的this related Twitter thread建议,解决这个问题的方法是使项目标识符类型仅表示显示单元格所需的属性。所以我更新了SearchHit的散列和相等比较,以包括标题的突出显示部分,这是他们以前没有的,然后我在每次更新时都会得到所有单元格的删除和插入动画,这是我不想要的。
这看起来像是reloadItemsWithIdentifiers应该do...right什么?
GitHub上的示例项目here。
发布于 2020-03-11 00:24:57
可区分的数据源API可能不是对单元格本身产生动画效果的正确工具。它适用于细胞的出现、消失和排序的动画。如果您的数据源有一个通过Hashable一致性表示的更改,api会将其视为更改和删除/插入等。
我的建议是从项目标识符中删除搜索文本,并让每个单元格观察搜索文本,并独立于数据源实现动画或重绘。
https://stackoverflow.com/questions/60620906
复制相似问题