相关疑难解决方法(0)

如何在不删除和插入 UITableViewDiffableDataSource 的情况下重新加载项目?

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

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

我这样声明数据源:

@property (retain) UITableViewDiffableDataSource<NSString *, SearchHit *> *dataSource;
Run Code Online (Sandbox Code Playgroud)

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

我的代码看起来像这样:

-(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];
}
Run Code Online (Sandbox Code Playgroud)

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

Donny Wals 的这篇文章和涉及 Steve Breen 的相关 Twitter 线程建议解决此问题的方法是使项目标识符类型仅表示显示单元格所需的属性。所以我更新了SearchHit的散列和相等比较以包含标题的突出显示部分,而他们以前没有。然后我在每次更新时删除并插入所有单元格的动画,这是我不想要的。

这看起来reloadItemsWithIdentifiers应该怎么做……对吧?

示例项目在这里 …

objective-c uitableview diffabledatasource nsdiffabledatasourcesnapshot

11
推荐指数
2
解决办法
2602
查看次数

NSFetchedResultsController + UICollectionViewDiffableDataSource + CoreData - 如何区分整个对象?

我正在尝试将 iOS 13 中内置的一些新差异类与 Core Data 一起使用。我遇到的问题是controllerdidChangeContentWith它没有按预期工作。它传递给我一个快照引用,它是对 a 的引用NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>,这意味着我得到了已更改的部分/对象 ID 的列表。

这部分效果很好。但是当您在集合视图中遇到差异时,问题就来了。在 WWDC 视频中,他们愉快地调用dataSource.apply(snapshot, animatingDifferences: true),一切都神奇地工作,但在实际 API 中并非如此。

在我最初的尝试中,我尝试了这个:

resolvedSnapshot.appendItems(snapshot.itemIdentifiersInSection(withIdentifier: section).map {
     controller.managedObjectContext.object(with: $0 as! NSManagedObjectID) as! Activity
}, toSection: .all)
Run Code Online (Sandbox Code Playgroud)

这适用于填充单元格,但如果单元格(即单元格标题)上的数据发生更改,则永远不会重新加载特定单元格。我查看了快照,似乎问题只是我引用了这些活动对象,因此它们都同时更新(意味着旧快照中的活动等同于新快照中的活动,因此哈希值相等。)

我当前的解决方案是使用一个包含我所有 Activity 类变量的结构,但这会将它与 CoreData 断开连接。所以我的数据源变成了:var dataSource: UICollectionViewDiffableDataSource<Section, ActivityStruct>这样快照实际上会得到两个不同的值,因为它有两个不同的对象要比较。这有效,但它似乎远非优雅,这就是我们打算使用它的方式吗?或者它现在只是处于破碎状态?WWDC 视频似乎暗示它不应该需要所有这些额外的样板。

core-data nsfetchedresultscontroller uicollectionview

5
推荐指数
1
解决办法
592
查看次数