Assertion Failure in UICollectionViewData
validateLayoutInRect
on iOS7.
I am trying to delete all UICollectionView
items, one by o
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
[collectionView.collectionViewLayout invalidateLayout];
return 1;
}
It looks like you probably want to do this:
[self.CollectionView performBatchUpdates:^(void) {
for (int i = count - 1; i >= 0; i--) {
[collectionArray removeObjectAtIndex:i]; // First delete the item from you model
[self.CollectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]];
}
} completion:nil];
So that all the updates are performed together. Otherwise you will end up trying to perform several lots of batch updates on top of each other.
In my case following delegate was missing:
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
in iOS 10 you must disable the prefetchingEnabled:
// Swift
if #available(iOS 10, *) {
collectionView.prefetchingEnabled = false
}
//Obj C
if ([self.collectionView respondsToSelector:@selector(setPrefetchingEnabled:)]) {
self.collectionView.prefetchingEnabled = false;
}
I actually got this crash one time not because I was returning zero for a number of sections or items in a section but because I was reusing a flow layout like this for more than 1 collection view:
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout];
[Collection1 setDataSource:self];
[Collection1 setDelegate:self];
[self.view addSubview:Collection1];
Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayout];
Collection2.backgroundColor = [UIColor whiteColor];
Instead if I create a new flow layout for each UICollectionView I avoid this crash. Hopefully that might help someone
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
Collection1 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 50.0f) collectionViewLayout:flowLayout];
[Collection1 setDataSource:self];
[Collection1 setDelegate:self];
[self.view Collection1];
UICollectionViewFlowLayout *flowLayoutVert = [[UICollectionViewFlowLayout alloc] init];
[flowLayoutVert setScrollDirection:UICollectionViewScrollDirectionVertical];
Collection2 = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, self.view.frame.size.height) collectionViewLayout:flowLayoutVert];
You should implement invalidateLayout in your layoutClass
and remove all kinds of UICollectionViewLayoutAttributes
items in your config.
- (void)invalidateLayout{
[super invalidateLayout];
[self.itemsAttributes removeAllObjects];
}