UICollectionViewData中的声明失败indexPathForItemAtGlobalIndex
我正在使用performBatchUpdates()来更新我的集合视图,在那里我正在做一个完整的刷新,即删除它里面的东西,并重新插入一切。 批量更新是作为附加到NSMutableArray
( bingDataItems
)的Observer的一部分完成的。
cellItems是包含正在或将要插入到集合视图中的项目的数组。
这里是代码:
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { cultARunner *_cultARunner = [cultARunner getInstance]; if ( [[_cultARunner bingDataItems] count] ) { [self.collectionView reloadData]; [[self collectionView] performBatchUpdates: ^{ int itemSize = [cellItems count]; NSMutableArray *arrayWithIndexPaths = [NSMutableArray array]; // first delete the old stuff if (itemSize == 0) { [arrayWithIndexPaths addObject: [NSIndexPath indexPathForRow: 0 inSection: 0]]; } else { for( int i = 0; i < cellItems.count; i++ ) { [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; } } [cellItems removeAllObjects]; if(itemSize) { [self.collectionView deleteItemsAtIndexPaths:arrayWithIndexPaths]; } // insert the new stuff arrayWithIndexPaths = [NSMutableArray array]; cellItems = [_cultARunner bingDataItems]; if ([cellItems count] == 0) { [arrayWithIndexPaths addObject: [NSIndexPath indexPathForRow: 0 inSection: 0]]; } else { for( int i = 0; i < [cellItems count]; i++ ) { [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; } } [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths]; } completion:nil]; } }
我得到这个错误,但不是所有的时间(为什么?)
2012-12-16 13:17:59.789 [16807:19703] *** Assertion failure in -[UICollectionViewData indexPathForItemAtGlobalIndex:], /SourceCache/UIKit_Sim/UIKit-2372/UICollectionViewData.m:442 2012-12-16 13:17:59.790 [16807:19703] DEBUG: request for index path for global index 1342177227 when there are only 53 items in the collection view
我检查了唯一提到这个问题的线程: UICollectionView Assertion失败 ,但它不是很清楚,即在performBatchUpdates()
块中不build议使用[collectionview reloadData]
。
有什么可能会出错的build议?
最后! 好的,这是导致这次事故的原因。
如前所述,我正在创build补充视图,以便为我的collections视图提供自定义样式的部分标题。
问题是这样的:补充视图的indexPath必须对应于集合中现存单元格的indexPath。 如果补充视图的索引path没有相应的普通单元格,则应用程序将崩溃。 我相信收集视图尝试检索补充视图的单元格由于某种原因在更新过程中的信息。 它无法find一个崩溃。
希望这也能解决你的问题!
这是这个崩溃的适当的解决方法:
每个补充视图都与某个索引path相关联。 如果在索引path中没有单元格(初始加载,已删除行等),请通过布局的代理为您的补充视图返回0的高度。
所以,对于stream布局,实现UICollectionViewDelegateFlowLayout的
(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
方法(和相应的页脚方法,如果您使用页脚)和以下逻辑
if ( you-have-a-cell-at-the-row-for-this-section ) return myNormalHeaderSize; else return CGSizeMake( 0,0 );
希望这可以帮助!
reloadData
不适用于我,因为使用performBatchUpdates
的全部目的是为了让animation变化。 如果使用reloadData
,则只刷新数据,但不带animation。
所以“用reloadData
replaceperformBatchUpdates
”的build议几乎是说“放弃你想做的事情”。
对不起,我只是感到沮丧,因为这个错误一直在为我而来,而我正在尝试做一些伟大的animation更新,我的模型是100%正确的,这是一些iOS的魔法里面破,迫使我改变我的解决scheme。
我的意见是,收集意见仍然是越野车,不能做复杂的animation更新,即使他们应该能够。 因为这对于表视图来说是相同的事情,但是现在相当稳定(虽然花了时间)。
//编辑(2013年9月1日)报告的bug现在已经closures,所以这个问题似乎已经被Apple解决了。
我一直有同样的问题。
我尝试了一些变化,但似乎工作的最后一个是[self.collectionView reloadData]
,其中"self.collectionView"
是您的集合视图的名称。
我已经尝试了以下方法,直接从“UICollectionView类参考”:插入,移动和删除项目。
这些东西最初被用来把这个东西从一个部分“移动”到另一个部分。
-
deleteItemsAtIndexPaths:
-
insertItemsAtIndexPaths:
接下来,我试着moveItemAtIndexPath:toIndexPath:
他们都产生了以下错误:
断言失败 – [UICollectionViewData indexPathForItemAtGlobalIndex:],/ SourceCache /UIKit_Sim/UIKit-2372/UICollectionViewData.m:442
所以,试试“reloadData”方法。
如果从包含页眉/页脚的部分删除最后一个单元格,则会出现该错误。
我试图返回零的头/页脚大小/元素,这有时可以解决这个问题。
选项:
- 重新加载整个表视图,而不是animation删除最后一个项目。
- 添加一个尺寸小于1的不可见的基本单元格。
可能导致此错误的cheeseball错误是在同一个viewcontroller上的多个collectionView上重复使用相同的UICollectionViewFlowLayout! 只需为每个collectionview初始化不同的flowLayouts,就可以开始了!
我遇到这个问题,当我从我的集合视图中删除一个单元格。
问题是我使用自定义布局,并且调用layoutAttributesForElementsInRect
比删除后的集合视图中的单元格数量多。
显然,UICollectionView只是遍历方法返回的数组而不检查单元的数量。
修改方法返回相同数量的布局属性解决了崩溃。
我仍然无法弄清楚全局索引是如何递增的,但是我通过在底层数据源数组(即cellItems
插入临时项并在viewDidLoad()
调用[self.collectionview reloadData]
来解决我的问题。
这会在集合视图中暂时插入一个占位符单元格,直到使用performBatchUpdates()
触发实际进程。