Validation error in UICollectionViewData indexPathForItemAtGlobalIndex

I use performBatchUpdates () to update my collection view, where I am doing a full update, i.e. I delete everything that was in it, and again insert everything. Package updates are performed as part of the Observer , which is bound to NSMutableArray ( bingDataItems ).

cellItems is an array containing the elements that will or will be inserted into the collection view.

Here is the code:

 - (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]; } } 

I get this error, but not at all times (why?)

 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 

I checked the only thread that mentioned the same problem: UICollectionView Assertion error , but this is not very clear, i.e. executing [collectionview reloadData] impractical in performBatchUpdates() .

Any suggestions on what might be wrong here?

+25
ios objective-c uicollectionview
Dec 16 '12 at 18:05
source share
8 answers

At last! Well, that’s what led to this disaster for me.

As noted earlier, I created additional views to provide custom-style section headings for my collection view.

The problem is this: it seems that the indexPath of the secondary view MUST match the PAT index from an existing cell in the collection. If the pointer path of the secondary view does not have a corresponding normal cell, the application will crash. I believe that viewing the collection is trying to get information for an additional view cell for some reason during the update procedure. He falls when he cannot find him.

Hope this solves your problem too!

+19
Mar 16 '13 at 21:26
source share

This is the correct workaround for this failure:

Each of your additional representations is associated with a specific index path. If you do not have a cell in this index path (boot, you deleted the row, etc.), return a height of 0 for your additional view through the layout delegate.

So, for the flow layout, we implement UICollectionViewDelegateFlowLayout

 (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section 

(and the corresponding footer method if you are using footers) with the following logic

 if ( you-have-a-cell-at-the-row-for-this-section ) return myNormalHeaderSize; else return CGSizeMake( 0,0 ); 

Hope this helps!

+17
Aug 23 '13 at 21:07 on
source share

reloadData does not work for me because the whole purpose of using performBatchUpdates is to get animated changes. If you use reloadData , you update the data only, but without animation.

Therefore, the sentences "replace performBatchUpdates with reloadData " pretty much say "give up what you are trying to do."

I'm sorry, I'm just disappointed because this error continues to come to me while I try to make some great animated updates, and my model is 100% correct, this is some iOS magic inside, which broke and made me completely change my decisions.

My opinion is that Collection Views is still not working and cannot perform complex animated updates, even if they should be able to. Because it was the same for Table Views, but now they are pretty stable (it takes time).

// Edit (September 1, 2013) The reported error is now closed, so these problems seem to have been resolved by Apple.

+8
Jan 02 '13 at 15:41
source share

I had the same problem.

I tried several options, but the last one that works is [self.collectionView reloadData] , where "self.collectionView" is the name of your collection view.

I tried the following methods, directly from the UICollectionView Class Reference: inserting, moving, and deleting elements.

At first they were used to β€œmove” an element from one section to another.

  • deleteItemsAtIndexPaths:

  • insertItemsAtIndexPaths:

Then I tried moveItemAtIndexPath:toIndexPath:

They all made the following error:

Assertion error in - [UICollectionViewData indexPathForItemAtGlobalIndex:], / SourceCache / UIKit_Sim / UIKit-2372 / UICollectionViewData.m: 442

So try the reloadData method.

+3
Dec 23 '12 at 6:52
source share

If you remove the last cell from the section containing the header / footer, an error will appear.

I tried to return nil for the size / element head / footer size / element at this time, and this one sometimes fixes the problem.

Options:

  • Reload the entire table view instead of an animation to delete the last item.
  • Add an extra invisible base cell smaller than 1.
+2
Apr 04 '13 at 7:59
source share

A cheese bug that can lead to this error is to reuse the same UICollectionViewFlowLayout in multiple collectible views on the same view controller! Just run different flowLayouts for each collector view, and you will be well off!

+2
Apr 25 '14 at 15:41
source share

I ran into this problem when I delete one of the cells from my collection view.

The problem was that I was using my own layout, and the call to layoutAttributesForElementsInRect returned more than the number of cells in the collection view after deletion.

Obviously, the UICollectionView simply iterates through the array returned by the method without checking the number of cells.

Modifying the method to return the same number of layout attributes resolved a failure.

+1
May 01 '13 at 2:23
source share

I still could not understand how the global index was so increased, but I solved my problem by inserting a temporary element into the underlying data array, i.e. cellItems and calling [self.collectionview reloadData] in viewDidLoad() .

This temporarily inserts the placeholder cell as a collection until I start the actual process using performBatchUpdates() .

0
Dec 27 '12 at 3:00
source share



All Articles