UICollectionView assertion error on stale data

UicollectionviewIos7

Uicollectionview Problem Overview


In the course of trying to unload one batch of images from my collection view and then replace them with another batch, I run into an error where, depending on whether the original or subsequent group of images was more or less than the intended replacement, an assertion error occurs which says:

*** Assertion failure in -[UICollectionViewData validateLayoutInRect:], 
/SourceCache/UIKit_Sim/UIKit-2891.1/UICollectionViewData.m:341
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', 
reason: 'UICollectionView recieved layout attributes for a cell with an 
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}

In this case the existing list of images count was 5 and the new list of images count was 2. So, when it got to the third image - the exception occurred - indicating that the UI CollectionViewDataDelegate did not know of the change in the data stream.

Any suggestions about how to make sure the new images will be referenced by the UICollectionView? Of course I have called 'reloadData'…

Thank you

Uicollectionview Solutions


Solution 1 - Uicollectionview

I run in the same problem. Code runs under 6.1 and crashes under 7.0 I solved the issue the following way:

In the function

-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView

I call

[myCollectionView.collectionViewLayout invalidateLayout];

That´s all.

Solution 2 - Uicollectionview

With iOS 10 and 11 this helps:

collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()

Invalidate layout should be AFTER reload data.

Solution 3 - Uicollectionview

Both Dominic Sander and user1544494 are right and their solutions are good.

Unfortunately, I've noticed that if you set minimumLineSpacingForSectionAtIndex or minimumInteritemSpacingForSectionAtIndex, the look of your collectionView is going to break (sooner or later).

Putting invalidateLayout in viewWillLayoutSubviews answers this question and helps preserving the look of viewCollection.

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    [viewCollection.collectionViewLayout invalidateLayout];
}

Solution 4 - Uicollectionview

It's simple. Just like that below sentence.

'UICollectionView recieved layout attributes for a cell with an 
index path that does not exist: <NSIndexPath: 0xb141c60> {length = 2, path = 0 - 2}

It's mean that there is no indexPath(0,2) on dataSouce. But, your UICollectionViewLayout return a UICollectionViewLayoutAttributes for indexPath(0,2).

You should return UICollectionViewLayoutAttributes just only exists on dataSouce.


I think that It was changed from iOS7.

Solution 5 - Uicollectionview

My problem was that I had two UICollectionViews inside one UIViewController. And I had both UICollectionViews connected to the same UICollectionViewLayout subclass. I fixed this problem by changing each UICollectionView to have their own UICollectionViewLayout subclass.

Source: This Question

Solution 6 - Uicollectionview

I fixed this crash by updating my collection view data source :

- (NSInteger)collectionView:(UICollectionView *)collectionView
     numberOfItemsInSection:(NSInteger)section
{
    [collectionView.collectionViewLayout invalidateLayout];
    return collectionArray.count;
}

Solution 7 - Uicollectionview

I had the same crash.

In my app, the problem was that I didn't empty the array with UICollectionViewLayoutAttributes. I'm using it in the prepareLayout() method to store the layout attribute for each cell.

var itemAttributes: Array<UICollectionViewLayoutAttributes> = Array<UICollectionViewLayoutAttributes>()

With just self.itemAttributes.removeAll() in the first line of prepareLayout, it works.

Solution 8 - Uicollectionview

I've experienced this problem after modifying the contents of the Collection View. The solution that worked in my case was to invalidate the layout after reload. Doing it before the reload will not work.

[collectionView reloadData];

//forces the layout attributes to be recalculated for new data
[collectionView.collectionViewLayout invalidateLayout];

Solution 9 - Uicollectionview

The solution I found was to ensure the indexPath I was creating in the layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? method is valid for the row. Previously, I was using (where i is my loop counter):

var indexPath = NSIndexPath(index: i)
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)

But updating it to use the following solved it:

var indexPath = NSIndexPath(forRow: i, inSection: 0)!
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)

Solution 10 - Uicollectionview

I was able to solve this issue by creating a subclass of UICollectionViewFlowLayout and overriding this method to return YES:

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}

Solution 11 - Uicollectionview

Make sure you update the contentSize of your collectionViewLayout. So after getting new images (2, instead of 5), recalculate the contentSize and set it.

Solution 12 - Uicollectionview

I have encountered with this issue and it was pretty annoying. My fix is to forget about UICollectionViewController and use instead regular UIViewController with UICollectionView inside.

Solution 13 - Uicollectionview

I've had this bug too and found a workaround. For me, the UICollectionView was launching this under iOS 7, working perfectly on iOS 8.

Check this article: https://stackoverflow.com/questions/27515673/whats-causing-this-ios-crash-uicollectionview-received-layout-attributes-for-a/28222293#28222293

In 2 words: Auto-Layout. Disable it on the view containing the UICollectionView and for me, it worked.

Solution 14 - Uicollectionview

The collectionViewLayout caches the layout attributes. In viewwillappear . Create a new instance of collectionViewLayout and assign it to collectionview.collectionViewLayout In this way all the cached attributes will purge before the reload Your problem might be resolved. Worked for me , especially when you are using other collectionViewLayout libraries.

Solution 15 - Uicollectionview

I had similar problem (using Swift2.0, XCode 7).

The app crashed with UICollectionView received layout attributes for a cell with an index path that does not exist...

In my case, since I used the storyboard, it just turned out that I forgot to connect the IBOutlet that was defined in my viewController with the actual collectionView defined in the storyboard. Connecting the two fixed the problem.

Solution 16 - Uicollectionview

I have figured it out. If you are using nib/xib to organize your UITableViewCell and nested UICollectionView,you can avoid this error by overriding this method.

- (void)prepareForReuse {

    [super prepareForReuse];
    [self.collectionView.collectionViewLayout invalidateLayout];
}

Hope it helps.

Solution 17 - Uicollectionview

> It's mean that there is no indexPath(0,2) on dataSouce. But, your UICollectionViewLayout return a UICollectionViewLayoutAttributes for indexPath(0,2). By TopChul

That's Right! For Me, the issue happened because I use same collection layout(instance) for two collectionView! So that layout confused between two collection View.

It work fine after I use different layout between different collection view.

Solution 18 - Uicollectionview

I ran into something similar when trying to duplicate a collection view into another storyboard.

> 'UICollectionView received layout attributes for a cell with an index > path that does not exist: {length = 2, path > = 1 - 0}'

At first, I am looking for a quick fix. Tried copy paste various StackOverflow answers.

But I wrote my own layout class. So I try to debug discreetly, it could be my implementation to blame, right? Found that numberOfSections method was never called. The collection view assumed that it had only one section.

Then I found view controller class forgot to conform to UICollectionViewDataSource. Though the dataSource was hooked up in the storyboard but probably the view controller class will be downcast, like if let ds = dataSource as? UICollectionViewDataSource {ds.numberOfSections...}, which would fail silently.

So I added the conformance to UICollectionViewDataSource and everything works fine. My guess could be inaccurate. But the lesson is whenever there's a bug you're not familiar with, settle down and understand it. UICollectionView received layout attributes for a cell with an index path that does not exist, it means exactly what it says. Not that hard right? Don't try to find a silver bullet, like many of the answers here. They are all great but your code is the real battle place.

Solution 19 - Uicollectionview

I run into the same problem when I use UICollectionViewFlowLayout as CollectionView's collectionViewLayout.

Declare the parent viewController implemented UICollectionViewDelegateFlowLayout and assign it as collectionView's delegate can solve this problem.

Solution 20 - Uicollectionview

In my case i had a custom UICollectionViewFlowLayout. After removing cells from the collectionView the app crashed. The fix was to removeAll() previously calculated attributes. So, first line after override func prepare() is arrayHoldingYourAttributes.removeAll().

Solution 21 - Uicollectionview

Hollo, I have the same issue while insert a collectionView into another collectionView and reloadData in main queue. Finally I reloadData before a new data convert to collectionView.

dispatch_async(dispatch_get_main_queue(), ^{
    [_collectionView reloadData];
});

_notes = notes;

[_collectionView reloadData];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1686700View Question on Stackoverflow
Solution 1 - UicollectionviewDominic SanderView Answer on Stackoverflow
Solution 2 - UicollectionviewMichał KwiecieńView Answer on Stackoverflow
Solution 3 - UicollectionviewGiuseppe GarassinoView Answer on Stackoverflow
Solution 4 - UicollectionviewTopChulView Answer on Stackoverflow
Solution 5 - UicollectionviewJohann BurgessView Answer on Stackoverflow
Solution 6 - UicollectionviewmeghaView Answer on Stackoverflow
Solution 7 - UicollectionviewBeujView Answer on Stackoverflow
Solution 8 - UicollectionviewricosrealmView Answer on Stackoverflow
Solution 9 - UicollectionviewSam YoutseyView Answer on Stackoverflow
Solution 10 - UicollectionviewSnowmanView Answer on Stackoverflow
Solution 11 - UicollectionviewAnupam ChakravortyView Answer on Stackoverflow
Solution 12 - UicollectionviewPavel SharandaView Answer on Stackoverflow
Solution 13 - UicollectionviewEric GiguereView Answer on Stackoverflow
Solution 14 - UicollectionviewAnkish JainView Answer on Stackoverflow
Solution 15 - Uicollectionviewda-naView Answer on Stackoverflow
Solution 16 - UicollectionviewtounaobunView Answer on Stackoverflow
Solution 17 - Uicollectionviewanonymous developerView Answer on Stackoverflow
Solution 18 - UicollectionviewjchnxuView Answer on Stackoverflow
Solution 19 - UicollectionviewChaoTangChangView Answer on Stackoverflow
Solution 20 - UicollectionviewPantelis ProiosView Answer on Stackoverflow
Solution 21 - UicollectionviewZehua LinView Answer on Stackoverflow