最近我收到以下错误:
致命异常:NSInternalInconsistencyException 无效更新:第0部分中的项目数无效。更新后的现有部分中包含的项目数(13)必须 等于该部分之前包含的项目数 更新(12),加上或减去插入或删除的项目数 从该部分(0插入,0删除)和加号或减号 物品移入或移出该部分(0移入,0移出)。
错误发生在我的tvOS客户端的以下代码中:
let removedIndexPaths = removedIndexes.map({ IndexPath(row: $0, section: 0) })
let addedIndexPaths = addedIndexes.map({ IndexPath(row: $0, section: 0) })
let updatedIndexPaths = updatedIndexes.map({ IndexPath(row: $0, section: 0) })
self.collectionView?.performBatchUpdates({
self.collectionView?.deleteItems(at: removedIndexPaths)
self.collectionView?.insertItems(at: addedIndexPaths)
}, completion: { _ in
guard let collectionView = self.collectionView else {
return
}
for indexPath in updatedIndexPaths {
if let myCell = collectionView.cellForItem(at: indexPath) as? MyCollectionViewCell {
let item = self.dataManager.items[indexPath.row]
myCell.updateUI(item)
}
}
let collectionViewLayout = self.collectionViewLayoutForNumberOfItems(self.dataManager.items.count)
if collectionViewLayout.itemSize != self.collectionFlowLayout.itemSize {
collectionView.setCollectionViewLayout(collectionViewLayout, animated: false)
}
})
我只在集合视图中使用了一个部分:
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
我已经查看了几个关于同一主题的帖子,但是他们还没有解决我的问题,我的猜测是问题出在以下两行,但我不确定:
self.collectionView?.deleteItems(at: removedIndexPaths)
self.collectionView?.insertItems(at: addedIndexPaths)
请帮忙。
答案 0 :(得分:5)
对insertItems(at:)和deleteItems(at:)的调用也必须伴随数据源的更改。
因此,在调用这些API之前,您需要更改数据源,即在调用insertItems
之前将对象添加到其中,并在调用deleteItems
之前从中删除对象
答案 1 :(得分:0)
找到一篇关于 UICollectionView invalid number of items 崩溃问题的非常好的文章 - https://fangpenlin.com/posts/2016/04/29/uicollectionview-invalid-number-of-items-crash-issue/
collectionView(_:numberOfItemsInSection:) 返回的项目计数应该与闭包内部所做的更新同步。考虑到这个想法,解决起来很容易,只需添加一个属性作为项目计数并在 performBatchUpdates 闭包中更新它
func updateItems(updates: [ItemUpdate]) {
collectionView.performBatchUpdates({
for update in updates {
switch update {
case .Add(let index):
collectionView.insertItemsAtIndexPaths([NSIndexPath(forItem: index, inSection: 0)])
itemCount += 1
case .Delete(let index):
collectionView.deleteItemsAtIndexPaths([NSIndexPath(forItem: index, inSection: 0)])
itemCount -= 1
}
}
}, completion: nil)
}
对于 collectionView(_:numberOfItemsInSection:),我们不返回 items.count,而是返回由 performBatchUpdates 闭包手动维护的属性。
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return itemCount
}