2011-01-31 25 views
7

Aggiungo diversi CALayer come sottolivelli del livello di un UIView. Il contenuto di ogni livello è un'immagine diversa scaricata da un server. Ogni livello è animato da fuori schermo in una posizione generata casualmente. I dati dell'immagine vengono scaricati in modo asincrono. Ogni immagine è di circa 300x300 o più piccola.Ottimizzazioni del CALayer?

Come risultato del posizionamento casuale, gli strati si sovrappongono e alcuni sono oscurati dagli strati sopra di essi. Va tutto bene.

Sto rimuovendo i livelli man mano che diventano completamente nascosti alla vista utilizzando il suggerimento in the answer to this question I calcoli per determinare la copertura si verificano su una filettatura separata.

Possiedo un UIPanGestureRecognizer che consente all'utente di trascinare i livelli sullo schermo.

Sto riscontrando un problema di prestazioni quando il numero di livelli aggiunti si avvicina a 25-30 e peggiora progressivamente. Le animazioni diventano discontinue e spesso sono completamente assenti (i nuovi livelli aggiunti appaiono semplicemente nella loro posizione finale). E i gesti pan sono ignorati o comportano un riposizionamento incoerente del livello selezionato.

Suppongo che sto uccidendo la GPU con tutti i livelli sovrapposti e un altro livello che anima sopra?

Qualche suggerimento su come migliorare le prestazioni?

Le migliori pratiche per gestire un numero elevato di livelli?

È preferibile che il livello venga animato in un view.layer separato rispetto ai livelli aggiunti in precedenza?

Grazie!

risposta

4

Un paio di cose veloci da controllare.

Eseguire lo strumento di animazione di base e cercare l'opacità. Basta impostare il flag opaco del livello su SÌ non è sufficiente, se l'immagine sottostante ha un componente alfa il livello prenderà in considerazione questo.

Se i dati che si ottengono dal proprio server hanno alpha, è necessario ridisegnare con Quartz e salvare il file localmente nel nuovo formato che non include alpha.

Assicurati doppiamente che non stai mettendo immagini da 1 mega pixel in tessere 100x100. Inoltre, Core Animation Instrument, attiva "Immagini disallineate di colore" e cerca il giallo.

Da 30 a 50 strati non dovrebbero costituire un problema.

+0

Grazie Bill. Darò un colpo. Avevo l'impressione che l'opaco fosse ignorato quando fornivo layer.contents (usato solo quando viene disegnato un livello?). Il bit alfa sarà più complicato - sto usando un bordo trasparente largo 2px attorno al bordo delle immagini per lisciare i bordi ruotati. Off to Instruments !! – TomH

+0

Ciao Tom - sì opaco viene ignorato a meno che non si disegni, puoi pensarlo come il secondo argomento di UIGraphicsBeginImageContextWithOptions, se il tuo contenuto ha un canale alfa allora il livello sarà trasparente - se hai tempo per favore scrivi un bug riguardo al bordoAntialiasingMask flag –

+1

Eccezionale.Stavo aggiungendo un canale alfa alla mia UIImage, aggiungendo un bordo trasparente 2px e poi usando l'immagine come contenuto per il livello. Perf è notevolmente migliorato non aggiungendo il bordo alfa e trasparente - nessun problema con> 30 livelli. Sfortunatamente, il bordo AntialiasingMask non sembra avere alcun effetto. Presenterò un bug. – TomH

3

Se tutti i livelli non si adattano alla memoria o alla porzione di memoria della GPU, le cose rallenteranno molto. Il caricamento e lo scaricamento della memoria della GPU è considerato piuttosto lento rispetto ai livelli di compositing nella memoria della GPU. Dovrai sperimentare questo limite di memoria, poiché i dispositivi meno recenti hanno meno memoria GPU disponibile rispetto ai dispositivi più recenti.