7

Questa è la vista dell'app quando è in modalità verticale. enter image description hereLa vista raccolta non aggiorna il layout a rotazione

Quando è ruotato alla modalità orizzontale che appare così

enter image description here

La vista debugger mostra che il UIWindow non sta ruotando come mostrato qui enter image description here

Il UICollectionViewController viene creato tramite StoryBoard. Ho provato la sottoclasse UICollectionViewFlowLayout che implementa shouldInvalidateLayoutForBoundsChange, ma non risolve il mio problema.

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { 
    CGRect oldBounds = self.collectionView.bounds; 
    if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds)) { 
     return YES; 
    } 
    return NO; 
} 

Si prega di fornire idee su cosa controllare successivamente o richieste di codice aggiuntivo per il debug.

Modifica - Come suggerito da MirekE, ho tentato di aggiungere vincoli allo CollectionView ma non è stato possibile. Tutte le opzioni per Editor-> Pin non sono disponibili per CollectionView. enter image description here

Edit, la risposta ad Andrea -

ho scelto come target iOS8.3. La mia comprensione è che il metodo principale chiamato a rotazione è viewWillTransitionToSize:withTransitionCoordinator:, che è dallo UIContentContainerprotocol. Ho aggiunto il seguente al mio CollectionViewController, ma lo stesso problema persiste

-(void)viewWillTransitionToSize:(CGSize)size 
     withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator { 
    [self.collectionView.collectionViewLayout invalidateLayout]; 
    [self.collectionView reloadData]; 
} 
+0

sembra che tu abbia dato dei vincoli specifici per ogni cella, è necessario? –

+0

Vinay - sì c'è un vincolo 'topMargin' e' centerX' sull'etichetta all'interno della cella, ma nessun vincolo sulla cella stessa. – Idr

+0

Secondo il documento, penso che dovresti chiamare la super implementazione in 'viewWillTransitionToSize' ad un certo punto. –

risposta

1

Il problema era che la presa collectionView non era impostata correttamente. Dopo aver impostato il collectionView, tutto funziona correttamente.

collectionView presa non impostato:

enter image description here

collectionView presa insieme:

enter image description here

1

Sembra che è sufficiente trascinare la vista raccolta sulla tela, ma non ho aggiunto alcun vincolo. Quindi quando si ruota il dispositivo, la dimensione non cambia.

Nello storyboard selezionare la vista raccolta, quindi fare clic sull'icona Pin nella parte inferiore di Xcode e aggiungere vincoli per i margini superiore, sinistro, inferiore e destro. Dopo averlo fatto, la visualizzazione della raccolta dovrebbe ridimensionarsi a rotazione.

+0

La Vista raccolta è stata aggiunta automaticamente quando ho trascinato il Collection View Controller sulla tela. Ho aggiornato la domanda con uno screenshot per mostrare cosa succede quando provo a bloccare la Vista raccolta. Non sono disponibili opzioni per aggiungere vincoli. Puoi approfondire la tua risposta? – Idr

+0

Il mio suggerimento sarebbe per una vista raccolta trascinata su un controller esistente. Se si tratta di CollectionViewController, non è necessario fare nulla. Riempie correttamente lo spazio mentre ruoto il simulatore in un piccolo progetto che ho creato per testarlo proprio ora. Forse hai aggiunto del codice personalizzato che sovrascrive i valori predefiniti? Hai provato a commentare le tue personalizzazioni? – MirekE

9

Non so quale versione di iOS hai impostato come targeting, ma supponiamo che tu conosca il processo di rotazione ei metodi chiamati nel controller della vista mentre sta accadendo.
In uno di questi metodi non vi resta che chiamare:

[self.collectionView.collectionViewLayout invalidateLayout]; 

e magari in base al layout -reloadData
Non c'è bisogno di creare una sottoclasse.


EDIT

Io uso questo metodo, credo che non funziona perché si dovrebbe Ridefinisci layout la raccolta dopo che è ridimensionata:

- (void) willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { 
    [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator]; 


    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) { 
     [self.collectionView.collectionViewLayout invalidateLayout];    
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) { 
     [self.collectionView reloadData]; 
    }]; 

} 


Quello che sto facendo collegare il processo di invalidazione del layout per il processo di animazione.

+0

Ho aggiornato la domanda con una risposta alla tua risposta. – Idr

+0

Ho modificato la mia risposta – Andrea

4

Se si dispone di un'implementazione personalizzata di UICollectionViewLayout, cercare di ignorare i metodi:

override public func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool { 
    let bounds = self.collectionView!.bounds; 
    return ((CGRectGetWidth(newBounds) != CGRectGetWidth(bounds) || 
     (CGRectGetHeight(newBounds) != CGRectGetHeight(bounds)))); 
} 

override public func invalidateLayout() { 
    cache.removeAll() // remove layout attributes ans settings if they exist 
    super.invalidateLayout() 

} 

Cheers!