UICollectionView должен быть инициализирован ненулевым параметром макета.

Я новичок в UICollectionView, и я следую учебнику, который нашел в Интернете, но я застрял на ошибке, которую не могу понять. Вот немного контекста.

В отладчике вижу, что происходит следующее:

  • numberOfSectionsInCollectionView: вызывается, и я возвращаю 1
  • вызывается collectionView:numberOfItemsInSection: и я возвращаю размер модели (20)
  • collectionView:layout:sizeForItemAtIndexPath: вызывается один раз для каждого элемента в модели
  • collectionView:layout:insetForSectionAtIndex: называется
  • collectionView:cellForItemAtIndexPath: вызывается, и он падает на этой строке...

    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MyCell" forIndexPath:indexPath];
    

с этой ошибкой...

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

Когда я приостанавливаю выполнение в этой строке и проверяю консоль, оказывается, что есть макет...

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

UICollectionView является частью единственной сцены в раскадровке. В viewController.m нет других UICollectionView, созданных каким-либо образом.

У кого-нибудь есть идеи?


person Murray Sagal    schedule 28.10.2012    source источник
comment
Эта ошибка возникает, когда вы создаете новое представление коллекции с помощью alloc/init или new, а не добавляете объект макета при инициализации. Вы делаете новый вид коллекции где-нибудь?   -  person jrturton    schedule 28.10.2012
comment
@jrturton Не то, чтобы я знал. UICollectionView является частью единственной сцены в раскадровке. В viewController.m нет созданных каким-либо образом UICollectionView. Но с учетом сказанного и будучи новичком в представлениях коллекции, я не уверен, где макет связан с представлением коллекции.   -  person Murray Sagal    schedule 28.10.2012


Ответы (6)


Это сработало для меня:

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

Если вы создаете UICollectionView программно, требуется макет.

person Maz Naiini    schedule 04.11.2012
comment
извините, это не то. Как я уже упоминал в вопросе, это исходит из раскадровки, и, как показано в выводе консоли, существует допустимый макет для представления коллекции. Смотрите мой ответ, в чем проблема оказалась. - person Murray Sagal; 05.11.2012
comment
Да это тоже существенно. У вас был неправильный класс, назначенный ячейке. - person Maz Naiini; 05.11.2012

Как оказалось проблема была с registerClass:. У меня было это:

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

а должно было быть так:

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

Таким образом, метод удаления из очереди создавал UICollectionView вместо UICollectionViewCell.

person Murray Sagal    schedule 05.11.2012

Если вы программно создаете контроллер представления коллекции в UICollectionViewController, убедитесь, что метод UICollectionViewController init использует [super initWithCollectionViewLayout] вместо [super init], например:

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

Из: Справочник по классу UICollectionViewController: Обзор

person jki    schedule 22.04.2014

у меня такая же проблема, и моя была решена с помощью

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

вместо

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

Если ваш класс наследуется от UICollectionViewController или вы программно создаете UICollectionView, то при нажатии класса вы можете установить collectionViewLayout, как показано ниже.

let homeViewController = HomeViewContoller(collectionViewLayout:UICollectionViewLayout())
person Gurjinder Singh    schedule 30.01.2017

Я столкнулся с этой проблемой при возврате объекта UICollectionViewLayout с itemSize, равным self.view.bounds, до инициализации представления.

person brendan    schedule 20.02.2015