可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
回答1:
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.
回答2:
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];
}
回答3:
With iOS 10 and 11 this helps:
collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()
Invalidate layout should be AFTER reload data.
回答4:
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.
回答5:
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
回答6:
I fixed this crash by updating my collection view data source :
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
[collectionView.collectionViewLayout invalidateLayout];
return collectionArray.count;
}
回答7:
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.
回答8:
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];
回答9:
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)
回答10:
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;
}
回答11:
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.
回答12:
Make sure you update the contentSize
of your collectionViewLayout
. So after getting new images (2, instead of 5), recalculate the contentSize
and set it.
回答13:
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: What's causing this iOS crash? UICollectionView received layout attributes for a cell with an index path that does not exist
In 2 words: Auto-Layout. Disable it on the view containing the UICollectionView and for me, it worked.
回答14:
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.
回答15:
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.
回答16:
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.
回答17:
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.
回答18:
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.
回答19:
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.
回答20:
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];