2012-12-06 6 views
40

Le mie celle UICollectionView contengono UILabels con testo multilinea. Non conosco lo height dello UICollectionViewCells finché il testo non è stato impostato su UILabel.Ridimensiona celle UICollectionView dopo che i loro dati sono stati impostati

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

era il metodo iniziale ho guardato alle dimensioni UICollectionViewCells, tuttavia questo viene chiamato prima che le cellule vengono creati dal UIStoryboard. C'è un modo per impaginare la collezione e dimensionare le celle DOPO che sono state renderizzate, e conosco le dimensioni reali della cella?

+0

Questa è la migliore soluzione a questo problema: http: // StackOverflow.com/a/19518480/2147976 – codeburn

risposta

65

Penso che state cercando il metodo invalidateLayout è possibile chiamare il .collectionViewLayout proprietà della vostra UICollectionView. Questo metodo rigenera il tuo layout, che nel tuo caso significa anche chiamare -collectionView: layout: sizeForItemAtIndexPath:, che è il posto giusto per riflettere la dimensione desiderata dell'articolo. Jirune indica la giusta direzione su come calcolarli.

Un esempio per l'utilizzo di invalidateLayout può essere trovato here. Consultare anche la documentazione di UICollectionViewLayout su tale metodo:

Invalida il layout corrente e attiva un aggiornamento del layout.

Discussione:

È possibile chiamare questo metodo in qualsiasi momento per aggiornare le informazioni di layout. Questo metodo invalida il layout della vista raccolta stessa e ritorna immediatamente. Pertanto, è possibile chiamare questo metodo più volte dallo stesso blocco di codice senza attivare più aggiornamenti di layout. L'aggiornamento del layout effettivo si verifica durante il successivo ciclo di aggiornamento del layout della vista.

Edit:

Per storyboard vista collezione che contiene auto vincoli di layout, è necessario eseguire l'override viewDidLayoutSubviews metodo UIViewController e chiamare invalidateLayout raccolta layout di visualizzazione in questo metodo.

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 
    [yourCollectionView.collectionViewLayout invalidateLayout]; 
} 
+0

Sto seguendo il tuo approccio all'implementazione, c'è un problema che ho incontrato: dopo aver chiamato 'invalidateLayout' a volte le celle scompaiono/diventano invisibili, quindi non posso trovarle in' sizeForItemAtIndexPath' con 'cellForItemAtIndexPath'. A proposito, io uso le celle per ottenere le loro dimensioni, non ho un negozio separato per questo. –

+0

cool thx! molto più meglio di una ricarica dei dati – Raegtime

+0

Impressionante! Si era bloccato sulla larghezza della cella che non era cambiato in quanto è assegnato dal layout automatico, ma dopo aver letto questa soluzione l'ho capito. P.S. Ho messo il codice per il problema del layout automatico, spero non ti dispiaccia. – Kampai

4

Hey nel delegate metodo stesso di cui sopra, è possibile calcolare la dimensione UILabel utilizzando la strada sotto di difficile e restituire il UICollectionViewCellsize in base a tale calcolo.

// Calculate the expected size based on the font and 
    // linebreak mode of your label 
    CGSize maximumLabelSize = CGSizeMake(9999,9999); 

    CGSize expectedLabelSize = 
    [[self.dataSource objectAtIndex:indexPath.item] 
      sizeWithFont:[UIFont fontWithName:@"Arial" size:18.0f] 
     constrainedToSize:maximumLabelSize 
      lineBreakMode:NSLineBreakByWordWrapping]; 
3

sottoclasse UICollectionViewCell e sovrascrivere layoutSubviews come questo

la presente si cellule ancoraggio iniziali e finali bordo per CollectionView

override func layoutSubviews() { 
     super.layoutSubviews() 

     self.frame = CGRectMake(0, self.frame.origin.y, self.superview!.frame.size.width, self.frame.size.height) 
    } 
0
- (void)viewDidLoad { 
    self.collectionView.prefetchingEnabled = NO; 
} 

in IOS 10, prefetchingEnabled è YES di default . Quando YES, la vista di raccolta richiede le celle prima di quando verranno visualizzate. Porta ad un arresto anomalo in iOS 10

+1

Sebbene questo snippet di codice sia benvenuto e potrebbe fornire un aiuto, sarebbe [notevolmente migliorato se includesse una spiegazione] (// meta.stackexchange.com/q/114762) di * come * e * perché * questo risolve il problema problema. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo la persona che chiede ora! Si prega di [modificare] la risposta per aggiungere una spiegazione e fornire un'indicazione di quali limitazioni e ipotesi si applicano. –

+0

@TobySpeight In iOS10, prefetchingEnabled è SÌ per impostazione predefinita. Quando SÌ, la vista raccolta richiede le celle in anticipo rispetto a quando verranno visualizzate. Porta ad un crash in iOS10 –

+0

Sembra una buona spiegazione - per favore ** [modifica] ** la tua risposta per incorporarla. Grazie! –