2013-06-24 10 views
6

Quando un utente esegue un'azione, devo estrarre uno UICollectionView dal basso verso l'alto fino a una certa altezza. Poiché questo nuovo stato è totalmente facoltativo, la vista raccolta viene creata prima di essere presentata in questo modo. L'animazione dal basso verso l'alto viene eseguita utilizzando le modifiche alla proprietà constant di NSLayoutConstraint e una chiamata a [view layoutIfNeeded] in un blocco di animazione.Prevenzione dell'aspetto animato di UICollectionViewCell durante la presentazione di UICollectionView

Il problema è che, facendo le cose in questo modo, le celle appaiono in modo indesiderato: si espandono dall'angolo in alto a sinistra alla loro dimensione specificata. Vorrei che la vista della raccolta appaia e abbia tutte le celle già disposte nella dimensione e nell'aspetto finali.

Sono a conoscenza di cose come il metodo setAnimationEnabled: di UIView, ma non riesco a trovare come e dove dovrei usarlo (se è la strada da percorrere).

Suppongo che il problema sia dovuto alle celle della vista raccolta che vengono aggiunte alla gerarchia della vista subito prima del blocco di animazione che contiene la chiamata a [superview layoutIfNeeded]. Questo probabilmente porta UIKit a pensare che dovrebbe anche animare quelle modifiche al layout. In tal caso, probabilmente la soluzione potrebbe essere qualcosa lungo il percorso di esclusione dall'animazione, modifiche specifiche alla gerarchia della vista.

+0

esecuzione in alcuni bug simili nella mia richiesta - per Ad esempio, quando lo avvio in simulatore l'intera schermata dell'app si espande dall'angolo in alto a sinistra e alcune parti del testo a volte "saltano" fino all'angolo sinistro della loro superview e quindi si animano al loro posto. Allo stesso modo faccio diverse animazioni con vincoli in diverse parti della mia app. Gradirei una risposta a questa domanda :) –

risposta

10

L'espansione dall'angolo in alto a sinistra è in genere un sintomo di chiamata layoutIfNeeded in un blocco di animazione quando la vista originale non è mai stata impostata. Stai praticamente animando il passaggio iniziale del layout, in cui tutte le sottoview sono state avviate su CGRectZero.

per risolverlo avete bisogno di due cose:

  • Assicurarsi che il vincolo si sta modificando è legato alla posizione di della vista raccolta, non la dimensione. Con questo intendo che non stai presentando la tua vista collezione cambiando la sua altezza da zero al valore finale.
  • Chiama layoutIfNeeded prima di modificare il vincolo, quindi richiamalo di nuovo nel blocco di animazione dopo aver apportato la modifica. In questo modo stai solo animando la modifica che hai specificato per il vincolo, piuttosto che l'intero layout.
+1

Ha funzionato! Grazie mille! Per riferimento, ciò che ho scoperto è stato creare un vincolo a bassa priorità che avrebbe reso l'altezza della vista di raccolta uguale all'altezza della finestra, richiamare 'layoutIfNeeded', impostare un vincolo con priorità più alta che avrebbe sovrascritto quello precedente ed eseguire l'animazione ! E ha funzionato magnificamente! – matehat

+0

Sarò in grado di assegnare la taglia in sole 22 ore ... – matehat

+0

Sfruttare le priorità è una grande idea! Sto per scrivere qualcosa di simile anch'io e di solito mantengo riferimenti a vari vincoli, ma proverò a modo tuo questa volta. – jrturton

0

Sono stato in questo problema per circa 3 giorni e finalmente ho trovato una soluzione. Semplicemente ho aggiunto il blocco di animazione di essere chiamato dopo una piccolissima timer

UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: { 
      self.view.layoutIfNeeded() 
     }){ _ in} 

sarà

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
    dispatch_after(delayTime, dispatch_get_main_queue()) { 
     self.changeConstraint() 
    } 

private func changeConstraint(){ 

     UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: { 
      self.view.layoutIfNeeded() 
     }){ _ in} 
} 

vedere la magia :)

Problemi correlati