CALayer è la classe base per i livelli grafici in iOS, parte del framework QuartzCore. Ogni UIView in iOS ha un CALayer associato che gestisce il rendering del contenuto, l'animazione e la composizione sulla GPU. Secondo Apple QuartzCore Documentation, 2025, CALayer supporta oltre 40 proprietà animabili e funziona direttamente tramite Metal. Comprendere CALayer è essenziale per creare animazioni fluide e ottimizzare le prestazioni dell'interfaccia.
Punti chiave
CALayer è una classe del framework QuartzCore che gestisce un'immagine bitmap di un'area rettangolare dello schermo. Memorizza proprietà visive: frame, backgroundColor, opacity, shadow, border, transform. A differenza di UIView, CALayer non gestisce eventi tattili, non partecipa ad Auto Layout e non ha un ciclo di vita di view controller.
Architetturalmente, CALayer implementa il pattern Model nel contesto di Core Animation. Il livello memorizza lo stato delle proprietà visive, mentre Core Animation gestisce l'interpolazione tra gli stati durante l'animazione. Questa separazione consente di animare qualsiasi proprietà del livello senza dover ridisegnare il contenuto tramite drawRect.
Secondo Apple WWDC 2024, CALayer è stato riscritto per funzionare tramite Metal. La pipeline di rendering moderna include tre fasi: Commit (aggiornamento delle proprietà sulla CPU), Render (generazione di comandi GPU sulla CPU) e Composite (esecuzione dei comandi sulla GPU). CALayer partecipa a tutte e tre le fasi, fornendo dati per ciascuna.
Ogni livello può contenere sublayers — livelli figli che vengono renderizzati sopra il livello padre. La gerarchia dei livelli rispecchia la gerarchia di UIView ma può esistere indipendentemente da essa. Gli sviluppatori possono creare livelli indipendentemente da UIView tramite CALayer() e aggiungerli alla gerarchia tramite addSublayer.
UIView è un wrapper attorno a CALayer che aggiunge: gestione tattile tramite UIResponder, partecipazione ad Auto Layout, rappresentazione in storyboard e integrazione con UIViewController. CALayer è un oggetto leggero che può essere utilizzato senza UIView per elementi puramente visivi.
In pratica, ciò significa che se un elemento non necessita di gestione tattile o layout, può essere implementato come CALayer. Ad esempio, animazioni di sfondo, indicatori di caricamento, elementi decorativi — tutto questo è più efficiente da implementare tramite CALayer, evitando l'overhead di UIView.
Le proprietà di base di CALayer includono frame, posizionamento, visualizzazione ed effetti visivi. frame definisce l'area rettangolare del livello nelle coordinate del padre, bounds definisce le coordinate interne e position definisce il centro del livello. La modifica di position viene animata per default tramite animazione implicita.
La proprietà contents consente di impostare direttamente il contenuto bitmap — tramite CGImage o CIImage. Questa è un'alternativa al disegno tramite drawRect: se l'immagine è già pronta, può essere passata a contents e Core Animation la renderizzerà senza elaborazione aggiuntiva.
Per l'animazione vengono utilizzati CABasicAnimation, CAKeyframeAnimation e CATransition. Tutte queste classi funzionano tramite key path delle proprietà di CALayer, consentendo di animare praticamente qualsiasi attributo — da position a transform.rotation.z.
Apple fornisce diverse sottoclassi specializzate di CALayer, ciascuna per risolvere un compito specifico. Scegliere la sottoclasse appropriata invece del CALayer base può fornire miglioramenti significativi delle prestazioni grazie all'accelerazione hardware.
CAReplicatorLayer è particolarmente utile per creare pattern ripetitivi senza duplicazione di codice. Ad esempio, un indicatore di caricamento con 10 punti viene implementato con un singolo CAReplicatorLayer utilizzando instanceCount = 10 e offset temporale dell'animazione instanceDelay.
Il rendering di CALayer avviene in tre fasi. Commit — quando una proprietà del livello cambia, viene formato un lotto di modifiche sulla CPU. Render — Core Animation genera comandi Metal sulla CPU in base alle proprietà del livello. Composite — la GPU esegue i comandi e visualizza il frame sullo schermo. L'intero processo è sincronizzato con la frequenza di aggiornamento del display.
Durante la composizione di più livelli, la GPU li fonde nell'immagine finale tenendo conto di trasparenza, maschere e modalità di fusione. Se un livello ha opaque = true, Core Animation ottimizza la composizione: invece della fusione alpha, viene eseguita una semplice sostituzione di pixel, che è significativamente più veloce.
Secondo le Apple Performance Guidelines, i principali fattori che rallentano il rendering di CALayer sono: gerarchia complessa di sublayers (più di 30 livelli sullo schermo), uso di maschere (proprietà mask), calcolo automatico dell'ombra senza shadowPath e uso eccessivo di shouldRasterize per livelli dinamici.
Core Animation Instrument in XCode consente di monitorare il tempo di rendering di ogni livello, il numero di buffer offscreen e la frequenza delle chiamate drawRect. Il tempo di rendering ottimale per 60 FPS non supera 8 ms sulla CPU e 8 ms sulla GPU.
Rendering offscreen — renderizzare un livello in un buffer intermedio prima di visualizzarlo sullo schermo. Si verifica quando si utilizza cornerRadius + masksToBounds con contenuto, opacità di gruppo, maschere e shouldRasterize. Ogni passaggio offscreen richiede 2–5 ms, quindi i rendering offscreen eccessivi sono critici per le prestazioni.
Per diagnosticare il rendering offscreen, utilizzare lo strumento Color Offscreen-Rendered in Core Animation Instrument. Livelli gialli — offscreen, blu — rendering diretto sullo schermo. Minimizzare i passaggi offscreen è una tecnica chiave di ottimizzazione in iOS.
Il primo esempio mostra la configurazione di base di CALayer con creazione di ombra, arrotondamento angoli e bordo. shadowPath è specificato esplicitamente per accelerare il rendering:
import UIKit
func configureLayer(_ view: UIView) {
let layer = view.layer
layer.cornerRadius = 16
layer.borderWidth = 2
layer.borderColor = UIColor.systemBlue.cgColor
layer.backgroundColor = UIColor.white.cgColor
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.2
layer.shadowOffset = CGSize(width: 0, height: 4)
layer.shadowRadius = 8
layer.shadowPath = UIBezierPath(
roundedRect: view.bounds,
cornerRadius: layer.cornerRadius
).cgPath
}
Il secondo esempio mostra un'animazione di transform tramite CABasicAnimation con trasformazione 3D prospettica. L'animazione di rotazione sull'asse Y crea un effetto di capovolgimento carta:
let flipAnimation = CABasicAnimation(keyPath: "transform")
var transform = CATransform3DIdentity
transform.m34 = -1.0 / 500.0
transform = CATransform3DRotate(transform, .pi, 0, 1, 0)
flipAnimation.toValue = NSValue(caTransform3D: transform)
flipAnimation.duration = 0.8
flipAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
cardLayer.add(flipAnimation, forKey: "flip")
Il terzo esempio dimostra l'uso di CAGradientLayer per creare un gradiente di sfondo. Il gradiente viene renderizzato sulla GPU e non richiede risorse aggiuntive durante il ridimensionamento:
func addGradient(to view: UIView, colors: [UIColor]) {
let gradient = CAGradientLayer()
gradient.colors = colors.map { $0.cgColor }
gradient.locations = [0.0, 0.5, 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.frame = view.bounds
view.layer.insertSublayer(gradient, at: 0)
}
Domande frequenti
UIView è un wrapper attorno a CALayer che aggiunge gestione tattile, Auto Layout e integrazione con UIViewController. CALayer lavora solo con la presentazione visiva e l'animazione, rendendolo più leggero ed efficiente per compiti puramente grafici.
Oltre 40 proprietà, tra cui position, bounds, frame, opacity, backgroundColor, cornerRadius, transform, shadowOffset, shadowRadius, borderWidth e borderColor. L'animazione viene avviata automaticamente quando si modifica una proprietà all'interno di un blocco di animazione UIView.animate.
Imposta shadowPath — un contorno ombra esplicito come UIBezierPath. Senza shadowPath, Core Animation analizza il canale alfa del contenuto per calcolare la forma dell'ombra, richiedendo un passaggio aggiuntivo. Con shadowPath, l'ombra viene renderizzata come una semplice forma geometrica senza analisi del contenuto.
L'animazione implicita è l'animazione automatica quando si modifica una proprietà animabile di CALayer al di fuori di un blocco UIView.animate. La durata predefinita è di 0,25 secondi. Può essere disabilitata tramite CATransaction.setDisableActions(true) o impostata una durata personalizzata tramite CATransaction.begin/commit.
CAShapeLayer è più efficiente quando è necessario visualizzare una forma vettoriale — una linea, un cerchio, un poligono, un percorso complesso. Renderizza un path sulla GPU senza creare un buffer raster separato. Il CALayer base è adatto per aree rettangolari con sfondo, bordo e ombra.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche