在搜索多个部分时遇到异常。它发生在对数据源应用快照时。
背景:我有(预定义的(部分,每个部分都有一个项目集合。如果节中没有项目,则节不会显示在viewController中。项目是通过应用程序的一个功能添加的。一旦在其中一个节中添加了一个项,就会调用数据源更新,并显示添加了该项的节。
问题:尝试两次搜索不存在的项目时遇到此问题。要复制,您可以输入一个不存在的项目,然后通过退格删除搜索字符串,然后再次输入一个现有项目,然后在dataSource.apply((上抛出错误。
希望有人能帮忙。TIA!
这是代码:
func updateData(on searchItem: String = "") {
//create a snapshot that will be used by the datasource to apply the diff changes
snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
Manager.shared.getAllSections().forEach { section in
let items = section.items
//if search string is empty, we just assign the items of the section,
//else we filter it based on the searchItem
var filteredItems = searchItem.isEmpty ? items :
items.filter { $0.itemName.lowercased().contains(searchItem.lowercased()) }
//if theres no items filtered, we ain't appending any section and items
if filteredItems.count > 0 {
snapshot.appendSections([section])
snapshot.appendItems(filteredItems)
}
}
//when calling apply, i get the exception when calling apply on dataSource
dataSource.apply(snapshot, animatingDifferences: false)
}
//Here is the updateSearchResults delegate method triggered when typing something in the search bar
func updateSearchResults(for searchController: UISearchController) {
guard let searchedItem = searchController.searchBar.text, !searchedItem.isEmpty else {
updateData()
return
}
updateData(on: searchedItem)
}
好的,所以我认为这是可区分数据源中的某种类型的内部错误,当你的集合视图中有0个节时,它不喜欢,但我找到的解决方法是只添加一个伪节并隐藏节头(如果你有(。
在updateData((方法中,您可以添加:
if snapshot.numberOfItems == 0 {
snapshot.appendSections([YourSection(name: "dummy")])
}
然后,如果您使用的是一个节头,请为该伪节提供一些可识别的变量,您可以使用这些变量来隐藏标题。当对补充视图(标题(进行排队时;伪";如果是,则隐藏标题。
这是一个破解,但它最终看起来完全一样,你不必处理显示的丑陋的空部分。
我的理解是,当组合布局试图解析数据源中不存在的部分的布局时,就会发生这种情况。
在我的案例中,我使用的是UICollectionViewCompositionalLayout(sectionProvider:)
,当我的数据源返回正确但不同的部分时,它返回旧的部分。
我修复它的方法是使布局无效:collectionView.collectionViewLayout.invalidateLayout()