web-dev-qa-db-fra.com

UICollectionView doit être initialisé avec un paramètre de mise en page non nul

Je suis nouveau sur UICollectionView et je suis en train de suivre un tutoriel que j'ai trouvé sur le web mais je suis bloqué sur une erreur que je ne peux pas comprendre. Voici un peu de contexte.

Dans le débogueur, je peux voir que ce qui suit se produit:

  • numberOfSectionsInCollectionView: est appelé et je retourne 1
  • collectionView:numberOfItemsInSection: est appelé et je renvoie la taille du modèle (20)
  • collectionView:layout:sizeForItemAtIndexPath: est appelé une fois pour chaque élément du modèle
  • collectionView:layout:insetForSectionAtIndex: est appelé
  • collectionView:cellForItemAtIndexPath: est appelé et il plante sur cette ligne ...

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

avec cette erreur ...

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

Lorsque je suspends l'exécution sur cette ligne et vérifie la console, il semble qu'il y ait une disposition ...

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

Le UICollectionView fait partie de la seule et unique scène du storyboard. Dans viewController.m, il n'y a aucun autre UICollectionView créé par quelque moyen que ce soit.

Quelqu'un a-t-il une idée?

23
Murray Sagal

Il s'avère que le problème était avec registerClass:. J'avais ceci:

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

mais ça aurait dû être ça:

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

Ainsi, la méthode de dequeue créait un UICollectionView au lieu d'un UICollectionViewCell.

18
Murray Sagal

Cela a fonctionné pour moi:

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

Si vous créez UICollectionView par programme, une présentation est requise.

31
Maz Naiini

Si vous créez un contrôleur de vue de collection par programme dans UICollectionViewController, assurez-vous que la méthode UICollectionViewController init utilise [super initWithCollectionViewLayout] au lieu de [super init], par exemple:

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

De: Référence de classe UICollectionViewController: présentation

8
jki

j'ai le même problème et le mien a été résolu en utilisant

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

au lieu de

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

Si votre classe hérite de UICollectionViewController ou si vous créez UICollectionView par programme, alors en poussant la classe, vous pouvez définir collectionViewLayout comme ci-dessous

let homeViewController = HomeViewContoller(collectionViewLayout:UICollectionViewLayout())
1
Gurjinder Singh

Je rencontrais ce problème lors du retour d'un objet UICollectionViewLayout avec itemSize égal à self.view.bounds avant que la vue n'ait été initialisée.

0
brendan