UICollectionView assertion error on stale data
UicollectionviewIos7Uicollectionview 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:
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];