1

在多个部分进行搜索时出现异常。在数据源上应用快照时会发生这种情况。

背景:我有(预定义的)部分,每个部分都有一个项目集合。如果节中没有项目,节将不会出现在 viewController 中。通过应用程序的功能添加项目。在其中一个部分中添加项目后,将调用数据源更新并将显示添加了该项目的部分。

问题:尝试两次搜索不存在的项目时遇到此问题。要重现,您可以输入一个不存在的项目,然后通过退格删除搜索字符串,然后再次输入一个不存在的项目,然后 dataSource.apply() 将抛出错误。

希望有人可以提供帮助。蒂亚!

这是代码:

    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)
    }
4

2 回答 2

1

好的,所以我认为这是 diffable 数据源中的某种内部错误,当您的集合视图中有 0 个部分时,它不喜欢它,但我想出的解决方法是添加一个虚拟部分并隐藏部分标题(如果你有一个)。

在您的 updateData() 方法中,您可以添加:

if snapshot.numberOfItems == 0 {
    snapshot.appendSections([YourSection(name: "dummy")])
}

然后,如果您使用的是节标题,请为该虚拟节提供一些可识别的变量,您可以使用该变量来隐藏标题。将补充视图(标题)出列时,检查 name == "dummy" 如果是,则隐藏标题。

这是一个 hack,但最终看起来完全相同,您不必处理显示的丑陋的空白部分。

于 2020-07-25T19:05:30.483 回答
0

My understanding is that that happens when the compositional layout is trying to resolve layout for a section that doesn't exist in the data source.

In my case I was using UICollectionViewCompositionalLayout(sectionProvider:) which was returning old sections when my data source was returning the correct ones but different.

How I fixed it was invalidating the layout: collectionView.collectionViewLayout.invalidateLayout()

于 2022-01-17T09:31:39.903 回答