Assertion Failure in UICollectionViewData validateLayoutInRect on ios7

20,111

Solution 1

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

Solution 2

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

Solution 3

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.

Solution 4

layout lifecycle

You should implement invalidateLayout in your layoutClass and remove all kinds of UICollectionViewLayoutAttributes items in your config.

- (void)invalidateLayout{
  [super invalidateLayout];
  [self.itemsAttributes removeAllObjects];
}

Solution 5

try to call [yourCollectionView.collectionViewLayout invalidateLayout];

Share:
20,111

Related videos on Youtube

user1888996
Author by

user1888996

Updated on July 09, 2022

Comments

  • user1888996
    user1888996 almost 2 years

    Assertion Failure in UICollectionViewData validateLayoutInRect on iOS7.

    I am trying to delete all UICollectionView items, one by one, using a for loop; I posted my code below. I delete the UICollectionView items using deleteItemsAtIndexPaths. It's working perfectly on iOS6, but crashes in iOS7 with this exception:

    Assertion Failure in UICollectionViewData validateLayoutInRect

    I delete the object from collectionArray then self.collectionView, one by one, using indexPath. When I delete the 4th object its raises Assertion failure on iOS7. Here I am using performBatchUpdates.

    Please help me get the proper result in iOS7. Share proper code. Thanks in advance.

    try  {    
        for (int i=count-1; i>=0; i--)  {  
            [self.collectionView performBatchUpdates:^(void){  
                [collectionArray removeObjectAtIndex:i]; // First delete the item from you model   
                [self.collectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]];  
            } completion:nil];
            [self.collectionView reloadData];
        }
    }
    @catch (NSException *exception) {
    }
    @finally {
    }
    
    • Ivan Lisovyi
      Ivan Lisovyi over 10 years
      looks like you have the same problem as mentioned in: stackoverflow.com/questions/18189311/… and stackoverflow.com/questions/18339030/…
    • Mecki
      Mecki over 5 years
      @IvanLisovyi The first one is a crash when sending a message to an object whereas this here is an exception thrown by a failing assertion. No relationship whatsoever. The 2nd one may be related but I cannot say for sure as it's not said here what exception is thrown exactly.
  • Nitesh
    Nitesh almost 9 years
    I am doing the same thing but to no avail.
  • WeZZard
    WeZZard over 8 years
    A big help. Save my tons of time.
  • Chris Klingler
    Chris Klingler over 8 years
    Makes me glad I write some of these things down when it actually helps someone.
  • Superwayne
    Superwayne over 7 years
    This causes a stack overflow.
  • Arslan
    Arslan over 6 years
    You sir are a life saver. Thanks. It really fixed my problem as I am using a custom FlowLayout class.
  • dang
    dang over 6 years
    kisses and hags
  • Ravi Raja Jangid
    Ravi Raja Jangid over 6 years
    Yes iUser You can do that or By opening Attribute-inspector pan in storyboard for that particular collection-view by uncheck the prefetch property.