Migliori animazioni iOS con CATransaction

Core Animation, il framework Cocoa responsabile della maggior parte delle animazioni iOS e macOS, è un sistema complesso con molte funzionalità nascoste e meno conosciute.

Core Animation gestisce le tue animazioni dietro le quinte e conoscendo un po 'di più come funziona possiamo trarne il massimo vantaggio e creare animazioni ottimizzate.

Le animazioni sono facili. Tranne quando non lo sono.
BetterAnimations.playground

Le animazioni sono il modo migliore per visualizzare le modifiche a un utente. UIKit di Apple (o AppKit per macOS) rende un salto nelle animazioni un gioco da ragazzi. Probabilmente hai usato UIKit per la maggior parte dei tuoi incontri di animazione e probabilmente il codice è simile al seguente:

È pulito e facile da usare. I framework UIKit / AppKit di livello superiore (che si trovano sopra Core Animation) fanno un ottimo lavoro nel rendere facili le animazioni. Tuttavia, ci sono alcune insidie ​​quando si desidera movimenti più complessi.

Animazione di esempio

Considera questo: hai un UIButton, un discendente di UIView, e vuoi renderlo una vista circolare, e quando toccato cambierà la dimensione della vista.

Sembra diretto. Possiamo animare styledButton.layer.cornerRadius e impostarlo a metà della larghezza quando cambia il nostro frame. Ma aspetta ... c'è un problema. UIView.animate (...) gestirà solo animazioni di proprietà di visualizzazione e non animazioni di proprietà di livello. Se provassimo a cambiare la cornice di styledButton e cornerRadius di styledButton nel blocco di animazione qui sotto otteniamo un effetto indesiderato:

Risultato del segmento di codice

La cornice si anima correttamente, tuttavia cornerRadius passa direttamente al suo nuovo valore senza animare. Più avanti parleremo di CATransaction e di come risolverà questo problema. Ma prima, è bene sapere cosa sta succedendo sotto il cappuccio delle nostre animazioni e perché ciò accade.

Animazione interna

Le istanze UIView (così come le istanze NSView supportate da layer) hanno una proprietà CALayer chiamata layer su cui operano le animazioni. La vista delega il rendering dei loro livelli all'animazione principale. Tuttavia, quando le animazioni vengono aggiunte al livello, le proprietà del livello non vengono modificate direttamente.

Animazione principale contiene due gerarchie di alberi paralleli: un albero del livello modello e l'albero del livello di presentazione. Questi possono essere visualizzati nelle proprietà PresentationLayer e modelLayer di CALayer. È lo strato di presentazione che è responsabile della visualizzazione di eventuali cambiamenti nel corso di un'animazione. Se si dovesse animare la proprietà borderWidth di un livello e osservare il valore durante l'animazione, il valore borderWidth cambierà solo nell'albero del livello di presentazione durante l'animazione.

Con CABasicAnimation possiamo animare le proprietà dei layer. Ma non lasciare che la parola "Base" ti scoraggi - questo è uno dei più potenti strumenti di animazione per perfezionare le tue animazioni.

Nota pratica: è buona norma impostare il valore che si sta animando sul nuovo valore prima di aggiungere l'animazione. È comune vedere la proprietà fillMode impostata su kCAFillModeForwards e isRemovedOnCompletion impostata su false. Tuttavia, ciò che fa è essenzialmente "mettere in pausa" il nostro livello di presentazione alla fine dell'animazione. È buona norma mantenere sincronizzati i livelli del modello e della presentazione e impostando il valore prima di aggiungere l'animazione possiamo fare proprio questo.

CATransaction - Per rendere più fluide le tue animazioni

Ok. Torna al nostro esempio UIButton dai precedenti. Vogliamo animare la proprietà cornerRadius del layer e animare allo stesso tempo la proprietà frame della vista e assicurarci che rimangano perfettamente sincronizzati per la migliore animazione.

CATransazione in soccorso!

CATransaction è una classe spesso trascurata dalla maggior parte degli sviluppatori. Il compito di CATransaction è di raggruppare più azioni correlate all'animazione. Assicura che le modifiche all'animazione desiderate vengano impegnate contemporaneamente in Core Animation.

Qui iniziamo una transazione e possiamo modificare qualsiasi proprietà abilitata per Core Animation, che verrà animata una accanto all'altra una volta impegnata.

Mettere tutto insieme

Quindi vogliamo animare il layer e visualizzare le proprietà allo stesso tempo. Questo è un uso perfetto per CATransaction. Possiamo persino utilizzare il nostro codice UIView.animate () e CABasicAnimation esistente!

Animazione risultante

In questo esempio utilizzo sia un'animazione UIView sia un CABasicAnimation per completare questa attività. Qualsiasi cosa coordinata da CATransaction verrà trasmessa ad altre animazioni. Ad esempio, la funzione setAnimationDuration (dur: CFTimeInterval) verrà applicata a CABasicAnimation, quindi non è necessario specificare alcuna durata. Tuttavia, poiché UIView.animate () ci fa specificare la durata, possiamo semplicemente impostare la durata sulla stessa specificata in setAnimationDuration di CATransaction.

Animazioni di fotogrammi chiave personalizzati

Un altro uso accurato è utilizzare la funzione di timing di CATransaction per definire la propria curva di animazione più bezier. Se avvolgi il tuo UIView.animate () all'interno di una CATransaction puoi ottenere un controllo preciso sulla curva dell'animazione:

Animazione finale con funzione di temporizzazione

Sommario

CATransaction è un potente coordinatore per le tue animazioni e ti farà risparmiare un sacco di tempo dandoti il ​​controllo preciso sulle tue animazioni. Inoltre, non c'è un mucchio di blocchi nidificati - che è sempre un vantaggio di leggibilità.

Il progetto completo del parco giochi Swift 3 che utilizza CATransaction insieme a UIKit e CABasicAnimation è disponibile qui:

Grazie per aver letto! Se hai domande o suggerimenti, sentiti libero di contattarci!