简体   繁体   中英

UICollectionView not recognized in collectionView numberOfItemsInSection:

I have a problem I can't solve for some hours now...

I have multiple UICollectionViews with different numbers of cells and different cellsizes. The CollectionViews are created programmatically and the delegates and datasources are set.

The collectionviews are created like this:

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
collectionViewOne = [[UICollectionView alloc] initWithFrame:CGRectMake(0,0,320,150) collectionViewLayout:layout];
[collectionViewOne setTag:99];
[collectionViewOne setDataSource:self];
[collectionViewOne setDelegate:self];
[collectionViewOne registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
[collectionViewOne setBackgroundColor:bgColor];
[collectionViewOne setShowsHorizontalScrollIndicator:NO];
[collectionViewOne setBounces:YES];
[collectionViewOne setAlwaysBounceHorizontal:YES];
[collectionViewOne setScrollEnabled:YES];
[collectionViewOne setRestorationIdentifier:@"collectionViewOne"];
[scrollView addSubview:collectionViewOne];

My functions are like these:

- (NSInteger)collectionView:(UICollectionView*)collectionView numberOfItemsInSection:(NSInteger)section {

    NSLog(@"restorationIdentifier: %@", collectionView.restorationIdentifier);

    if (collectionView == collectionViewOne)
    {
        return 3;
    }
    else if (collectionView == collectionViewTwo)
    {
        return 4;
    }
    else
    {
        return 1;
    }
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"restorationIdentifier: %@", collectionView.restorationIdentifier);

    if (collectionView == collectionViewOne)
    {
        return CGSizeMake(100, 150);
    }
    else if (collectionView == collectionViewTwo)
    {
        return CGSizeMake(200, 150);
    }
    else
    {
        return CGSizeMake(200, 150);
    }
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"restorationIdentifier: %@", collectionView.restorationIdentifier);

    if (collectionView == collectionViewOne)
    {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
        imageView.image = [UIImage imageNamed:@"image.png"]; 
        [cell addSubview:imageView];
    }
    else if (collectionView == collectionViewTwo)
    {
        //create cell of type 2
    }
    return cell;
}

In my log I get the following output (for example):

restorationIdentifier in numberOfItemsInSection: (null) restorationIdentifier in sizeForItemAtIndexPath : (null) restorationIdentifier cellForItemAtIndexPath: collectionViewOne

collectionViewOne is the restorationIdentifier on collectionViewOne. So why is it not recognized in the first two methods?

Ofcourse the result is that I get crashes because the cellsizes and number of cells in the different CollectionViews are not properly set. The error:

*** Assertion failure in -[UICollectionViewData validateLayoutInRect:], /SourceCache/UIKit_Sim/UIKit-2903.2/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: 0x8c31c10> {length = 2, path = 0 - 2}'

How can I fix this?

This is solved. The problem was the fact that I used the same UICollectionViewFlowLayout for both UICollectionViews. This caused the exception.

In the end I used different classes for the two controllers, this solved the problem of selecting the right CollectionView in the delegate's methods.

Thanks all for your input!

You could use the tag property of the collection view to identify which collection view is which. Like this:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"restorationIdentifier: %@", collectionView.restorationIdentifier);

    if (collectionView.tag == collectionViewOneTag)
    {
        //create cell of type 1
    }
    else if (collectionView.tag == collectionViewTwoTag)
    {
        //create cell of type 2
    }

    return cell;
}

Where collectionViewOneTag and collectionViewTwoTag are integers that can be defined in code or in the xib file.

Hope that helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM