2016-04-27 24 views
16

Ho utilizzato UICollectionView (flowlayout) per creare un layout semplice. la larghezza per ogni cella è impostata sulla larghezza dello schermo utilizzando self.view.frame.widthSwift: Come aggiornare il layout di UICollectionView dopo la rotazione del dispositivo

ma quando ruoto il dispositivo, le celle non vengono aggiornate.

enter image description here

ho trovato una funzione, che è chiamato il cambiamento dell'orientamento:

override func willRotateToInterfaceOrientation(toInterfaceOrientation: 
    UIInterfaceOrientation, duration: NSTimeInterval) { 
    //code 
} 

ma non riesco a trovare un modo per aggiornare il layout UICollectionView

Il codice principale è qui:

class ViewController: UIViewController , UICollectionViewDelegate , UICollectionViewDataSource , UICollectionViewDelegateFlowLayout{ 

    @IBOutlet weak var myCollection: UICollectionView! 

    var numOfItemsInSecOne: Int! 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     numOfItemsInSecOne = 8 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) { 

     //print("orientation Changed") 
    } 

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { 
     return 1 
    } 

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return numOfItemsInSecOne 
    } 

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cellO", forIndexPath: indexPath) 

     return cell 
    } 

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{ 
    let itemSize = CGSize(width: self.view.frame.width, height: 100) 
    return itemSize 
    }} 

risposta

13

Aggiungi questa funzione:

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    myCollection.collectionViewLayout.invalidateLayout() 
} 

Quando si modifica l'orientamento, questa funzione verrà chiamata.

+0

grazie @ khuong291 cosa succede se non ho alcun oggetto del mio CollectionView, e ho UICollectionViewController? come suppongo di chiamare reloadData? –

+2

UICollectionViewController ha già la proprietà 'collectionView', quindi basta chiamarli come dicevo. Basta modificarli in 'collectionView.reloadData()'. Funzionerà. – Khuong

+2

Quindi è necessario ricaricare la vista, non è sufficiente attivare un aggiornamento del layout? – Rivera

1

è possibile aggiornare il layout UICollectionView utilizzando

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 
    if isLandscape { 
     return CGSizeMake(yourLandscapeWidth, yourLandscapeHeight) 
    } 
    else { 
     return CGSizeMake(yourNonLandscapeWidth, yourNonLandscapeHeight) 
    } 
} 
27

L'opzione migliore è quella di chiamare invalidateLayout() invece di reloadData() perché non costringerà la ricreazione delle cellule, quindi le prestazioni saranno leggermente migliore:

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 
    myCollection.collectionViewLayout.invalidateLayout() 
} 
+0

Questo è il modo corretto. Questa dovrebbe essere la risposta accettata. – thesummersign

+0

questo è il modo corretto di farlo .. non i dati di ricarica di nuovo –

+3

che ha causato una cotta per me. e un loop infinito riconosciuto quando inserisco un'istruzione print nella funzione viewDidLayoutSubviews. – nyxee

3

Inoltre, è possibile invalidarlo in questo modo.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { 
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; 

    [self.collectionView.collectionViewLayout invalidateLayout]; 
} 
0

per aggiornare UICollectionViewLayouttraitCollectionDidChange metodo potrebbe essere utilizzato come bene:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { 
    super.traitCollectionDidChange(previousTraitCollection) 

    guard let previousTraitCollection = previousTraitCollections else { 
     return 
    } 
    collectionView?.collectionViewLayout.invalidateLayout() 
} 
0

I viewWillLayoutSubviews() non ha funzionato per me. Neanche ViewDidLayoutSubviews(). Entrambi hanno reso l'app un ciclo infinito che ho controllato usando un comando di stampa.

Uno dei modi che funzionano è

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 
// Reload here 
} 
Problemi correlati