我正在构建一个使用collectionView来显示食谱的应用程序。当用户滚动到底部时,我会调用我的服务器并获取更多食谱。目前,我在服务器响应新配方后调用reloadData()。这有效,但是当我需要做的就是加载新的配方时,它会重新加载所有内容。我已经阅读了类似的帖子,表明我可以使用insertItems - 但对我而言崩溃:libc ++ abi.dylib:以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)) - 崩溃。
答案 0 :(得分:1)
两个问题:
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.count
为2,因此您必须递减该值或使用半开放运算符。
如果代码仍然崩溃,请使用for
中包含的beginUpdates() / endUpdates()
循环,并在最后一个索引处逐个插入项目。