2012-10-28 1 views
21

Sono nuovo di UICollectionView e sto seguendo un tutorial che ho trovato sul Web ma sono bloccato su un errore che non riesco a capire. Ecco un po 'di contesto.UICollectionView deve essere inizializzato con un parametro di layout non nullo

Nel debugger posso vedere che segue sta accadendo:

  • numberOfSectionsInCollectionView: si chiama e torno 1
  • collectionView:numberOfItemsInSection: è chiamato e mi restituirà la dimensione del modello (20)
  • collectionView:layout:sizeForItemAtIndexPath: viene chiamato una volta per ogni elemento nel modello di
  • collectionView:layout:insetForSectionAtIndex: si chiama
  • collectionView:cellForItemAtIndexPath: g ets chiamati e si blocca su questa linea ...

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

con questo errore ...

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

Quando sospendere l'esecuzione su quella linea e controllare la console sembra che ci sia un layout ...

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

la UICollectionView fa parte l'unica scena nella storyboard. In viewController.m non ci sono altri UICollectionView s creati con qualsiasi mezzo.

Qualcuno ha qualche idea?

+2

Tale errore viene quando si effettua una nuova visione collezione utilizzando alloc/init o nuova , piuttosto che aggiungere un oggetto di layout quando si inizializza. Stai creando una nuova vista insieme da qualche parte? – jrturton

+1

@jrturton Non che io sappia. UICollectionView fa parte dell'unica scena dello storyboard. In viewController.m non ci sono UICollectionViews creati con qualsiasi mezzo. Ma con ciò detto, ed essendo nuovo per le viste di raccolta, non sono sicuro di dove il layout venga associato alla vista dell'insieme. –

risposta

18

Come risulta il problema era con registerClass:. Ho avuto questa:

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

ma avrebbe dovuto essere questo:

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

Quindi il metodo dequeue è stato la creazione di un UICollectionView invece di un UICollectionViewCell.

31

questo ha funzionato per me:

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

Se si sta creando UICollectionView di programmazione è necessario un layout.

+1

scusa, non è quello. Come ho accennato nella domanda questo sta uscendo da uno storyboard e come mostrato nell'output della console c'è un layout valido per la vista della collezione. Vedi la mia risposta per quale problema si è rivelato. –

+0

Sì, questo è anche essenziale. Hai avuto una classe sbagliata assegnata alla cella. –

8

Se si stanno facendo View Controller raccolta a livello di codice in UICollectionViewController assicurarsi che UICollectionViewController init metodo utilizza [Super initWithCollectionViewLayout] invece di [super-init], per esempio:

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

Da: UICollectionViewController Class Reference:Overview

3

ho avuto lo stesso problema e la mia ma ho risolto utilizzando

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

invece di

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

stavo correndo in questo problema quando si ritorna un oggetto UICollectionViewLayout con itemSize uguale a self.view.bounds prima della visualizzazione itialized.

0

Se la classe è Eredita da UICollectionViewController o si sta creando UICollectionView programmazione poi mentre si spinge la classe è possibile impostare collectionViewLayout come qui di seguito

let homeViewController = HomeViewContoller(collectionViewLayout:UICollectionViewLayout())