首页 > 解决方案 > insertItemsAt 集合视图崩溃

问题描述

我正在构建一个使用 collectionView 来显示食谱的应用程序。当用户滚动到底部时,我调用我的服务器并获取更多食谱。目前我在服务器响应新配方后调用 reloadData() 。这可行,但是当我需要做的只是加载新食谱时,它会重新加载所有内容。我读过类似的帖子,表明我可以使用 insertItems - 但对我来说,这会崩溃:libc++abi.dylib: terminating with uncaught exception of type NSException

这是我的代码:

func updateRecipes(recipesToAdd: Array<Recipe>) {
    let minNewRecipesIndex = (self.recipes.count + 1)
    recipes += recipesToAdd
    DispatchQueue.main.async {
        if recipesToAdd.count == self.recipes.count {
                self.collectionView?.reloadData()
        } else {
            let numberOfItems: [Int] = Array(minNewRecipesIndex...self.recipes.count)
            self.collectionView?.insertItems(at: numberOfItems.map { IndexPath(item: $0, section: 0) })
            // this crashes, but self.collectionView.reloadData() works
        }
    }
}

即使是简单的硬编码 - self.collectionView?.insertItems(at: IndexPath(item: 1, section: 0)) - 也会崩溃。

标签: swiftuicollectionview

解决方案


两个问题:

  • minNewRecipesIndex必须是self.recipes.count。想象一个空数组(.count== 0),在空数组中插入项目的索引是 0,而不是 1。

  • numberOfItems必须是Array(minNewRecipesIndex...self.recipes.count - 1)Array(minNewRecipesIndex..<self.recipes.count)。再次想象一个空数组。在索引 0 和 1 处插入两个项目,分别minNewRecipesIndex为 0 和self.recipes.count2,因此您必须减小值或使用半开运算符。

如果代码仍然崩溃,请使用一个for循环beginUpdates() / endUpdates()并在最后一个索引处逐个插入项目。


推荐阅读