Murray Sagal
Murray Sagal

Reputation: 8654

UICollectionView must be initialized with a non-nil layout parameter

I'm new to UICollectionView and I'm following a tutorial I found on the web but I'm stuck on an error I can't figure out. Here's a bit of context.

In the debugger I can see that following is happening:

with this error...

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UICollectionView must be initialized with a non-nil layout parameter'

When I pause execution on that line and check the console it appears that there is a layout...

(lldb) po collectionView.collectionViewLayout
(UICollectionViewLayout *) $4 = 0x07180fd0 <UICollectionViewFlowLayout: 0x7180fd0>

The UICollectionView is part of the one and only scene in the storyboard. In viewController.m there are no other UICollectionViews created by any means.

Does anyone have any ideas?

Upvotes: 23

Views: 35519

Answers (6)

Gurjinder Singh
Gurjinder Singh

Reputation: 10299

If your class is Inherit from UICollectionViewController or you are creating UICollectionView programmatically then while pushing the class you can set collectionViewLayout like below

let homeViewController = HomeViewContoller(collectionViewLayout:UICollectionViewLayout())

Upvotes: 1

Murray Sagal
Murray Sagal

Reputation: 8654

As it turns out the problem was with registerClass:. I had this:

[self.collectionView registerClass:[UICollectionView class] 
        forCellWithReuseIdentifier:@"MyCell"];

but it should have been this:

[self.collectionView registerClass:[UICollectionViewCell class] 
        forCellWithReuseIdentifier:@"MyCell"];

So the dequeue method was creating a UICollectionView instead of a UICollectionViewCell.

Upvotes: 18

brendan
brendan

Reputation: 1735

I was running into this issue when returning a UICollectionViewLayout object with itemSize equal to self.view.bounds before the view had been initialized.

Upvotes: 0

Shabeer Ali
Shabeer Ali

Reputation: 1033

i got the same problem and mine got solved by using

UICollectionViewFlowLayout *myLayout = [[UICollectionViewFlowLayout alloc]init];
[myLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[myLayout setMinimumInteritemSpacing:0.0f];
[myLayout setMinimumLineSpacing:0.0f];
UICollectionView *myCollectionView = [[UICollectionView alloc]initWithFrame:viewfame collectionViewLayout:myLayout];

instead of

UICollectionView *myCollectionView = [[UICollectionView alloc]initWithFrame:self.view.frame];
[myLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[myLayout setMinimumInteritemSpacing:0.0f];
[myLayout setMinimumLineSpacing:0.0f];
[myCollectionView setCollectionViewLayout:myLayout];

Upvotes: 3

jki
jki

Reputation: 4791

If you are making collection view controller programmatically in UICollectionViewController make sure that UICollectionViewController init method uses [super initWithCollectionViewLayout] instead of [super init], e.g.:

-(id) initWithImages:(NSArray *)pImages {
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    [layout setMinimumInteritemSpacing:0.0f];
    [layout setMinimumLineSpacing:0.0f];
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    if (self = [super initWithCollectionViewLayout:layout]) {
        _images= [[NSArray alloc] initWithArray:pImages];
    }
    return self;
}

From: UICollectionViewController Class Reference:Overview

Upvotes: 8

Maz Naiini
Maz Naiini

Reputation: 321

This worked for me :

UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
    [aFlowLayout setItemSize:CGSizeMake(200, 140)];
    [aFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
myCollectionViewController = [[MyCollectionViewController alloc]initWithCollectionViewLayout:flowLayout];

If you are creating UICollectionView programmatically a layout is required.

Upvotes: 32

Related Questions