UICollectionView Assertion failure

2019-01-07 04:00发布

I m getting this error on performing insertItemsAtIndexPaths in UICollectionView

Assertion failure in:

-[UICollectionViewData indexPathForItemAtGlobalIndex:], 
/SourceCache/UIKit/UIKit-2372/UICollectionViewData.m:442
2012-09-26 18:12:34.432  
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'request for index path for global index 805306367 
when there are only 1 items in the collection view'

I have checked and my datasource contains only one element. Any insights on why this could happen? If more information is needed I can definitely provide that.

14条回答
啃猪蹄的小仙女
2楼-- · 2019-01-07 04:47

Check that you are returning the correct number of elements in the UICollectionViewDataSource methods:

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

and

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
查看更多
Luminary・发光体
3楼-- · 2019-01-07 04:49

It seems that the problem occurs when you either insert or move a cell to a section that contains a supplementary header or footer view (with UICollectionViewFlowLayout or a layout derived from that) and the section has a count of 0 cells before the insertion / move.

I could only circumvent the crash and still maintain the animations by having an empty and invisible cell in the section containing the supplementary header view like this:

  1. Make - (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section return the actual cell `count + 1 for that section where the header view is.
  2. In - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath return

    if ((indexPath.section == YOUR_SECTION_WITH_THE_HEADER_VIEW) && (indexPath.item == [self collectionView:collectionView numberOfItemsInSection:indexPath.section] - 1)) {
            cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"EmptyCell" forIndexPath:indexPath];
    }
    

    ... an empty cell for that position. Remember to register the cell reuse in viewDidLoad or wherever you initialize your UICollectionView:

    [self.collectionView registerClass:[UICollectionReusableView class] forCellWithReuseIdentifier:@"EmptyCell"];
    
  3. Use moveItemAtIndexPath: or insertItemsAtIndexPaths: without crashing.
查看更多
登录 后发表回答