CALayer — este clasa de bază a straturilor grafice în iOS, parte a framework-ului QuartzCore. Fiecare UIView în iOS are un CALayer asociat care asigură randarea conținutului, animația și compoziția pe GPU. Conform Apple QuartzCore Documentation, 2025, CALayer suportă peste 40 de proprietăți care pot fi animate și funcționează direct prin Metal. Înțelegerea CALayer este necesară pentru a crea animații fluide și optimizarea performanței interfeței.
Principalele
CALayer — este o clasă din framework-ul QuartzCore care gestionează imaginea raster a unei zone dreptunghiulare a ecranului. Stochează proprietățile vizuale: frame, backgroundColor, opacity, shadow, border, transform. Spre deosebire de UIView, CALayer nu procesează evenimentele de atingere, nu participă la Auto Layout și nu are un ciclu de viață al unui view controller.
Arhitectural, CALayer implementează modelul Model în contextul Core Animation. Stratul stochează starea proprietăților vizuale, iar Core Animation gestionează interpolarea între stări în timpul animației. Această separare permite animarea oricăror proprietăți ale stratului fără a necesita redesenarea conținutului prin drawRect.
Conform Apple WWDC 2024, CALayer a fost rescris pentru a funcționa prin Metal. Pipeline-ul modern de randare include trei etape: Commit (actualizarea proprietăților pe CPU), Render (generarea comenzilor pentru GPU pe CPU) și Composite (executarea comenzilor pe GPU). CALayer participă în toate cele trei etape, furnizând date pentru fiecare.
Fiecare strat poate conține sublayers — straturi copil care sunt randate deasupra stratului părinte. Ierarhia straturilor repetă ierarhia UIView, dar poate exista separat. Dezvoltatorul poate crea straturi independent de UIView prin CALayer() și le poate adăuga în ierarhie prin addSublayer.
UIView — este un strat peste CALayer care adaugă: procesarea atingerilor prin UIResponder, participarea în Auto Layout, prezentarea în storyboard, integrarea cu UIViewController. CALayer — este un obiect ușor care poate fi folosit fără UIView pentru elemente pur vizuale.
În practică, aceasta înseamnă că dacă un element nu are nevoie de atingeri și layout, poate fi implementat ca CALayer. De exemplu, animații de fundal, indicatoare de încărcare, elemente decorative — toate acestea sunt mai eficiente implementate prin CALayer, evitând overhead-ul UIView.
Proprietățile de bază CALayer includ cadrul, poziționarea, afișarea și efectele vizuale. frame definește zona dreptunghiulară a stratului în coordonatele părintelui, bounds — coordonatele interne, position — centrul stratului. Modificarea position este animată implicit prin implicit animation.
Proprietatea contents permite setarea conținutului raster al stratului direct — prin CGImage sau CIImage. Aceasta este o alternativă la desenarea prin drawRect: dacă imaginea este deja gata, poate fi transmisă în contents, iar Core Animation o va randa fără procesare suplimentară.
Pentru animații se folosesc CABasicAnimation, CAKeyframeAnimation și CATransition. Toate aceste clase funcționează prin căi cheie ale proprietăților CALayer, ceea ce permite animarea practic a oricărui atribut — de la position până la transform.rotation.z.
Apple oferă mai multe subclase specializate ale CALayer, fiecare rezolvând o sarcină specifică. Alegerea subclasei potrivite în locul CALayer de bază poate oferi o creștere semnificativă a performanței datorită accelerării hardware.
CAReplicatorLayer este deosebit de util pentru crearea de modele repetitive fără duplicarea codului. De exemplu, un indicator de încărcare din 10 puncte se implementează cu un singur CAReplicatorLayer cu instanceCount = 10 și decalajul de timp al animației instanceDelay.
Randarea CALayer trece prin trei faze. Commit — la modificarea proprietății stratului pe CPU se formează un pachet de modificări. Render — Core Animation generează comenzi Metal pe CPU pe baza proprietăților stratului. Composite — GPU execută comenzile și afișează cadrul pe ecran. Întregul proces este sincronizat cu frecvența de reîmprospătare a afișajului.
La compoziția mai multor straturi, GPU le combină într-o imagine finală ținând cont de transparență, măști și moduri de amestecare. Dacă stratul are opaque = true, Core Animation optimizează compoziția: în loc de amestecare alfa, se execută o simplă înlocuire de pixeli, ceea ce este mult mai rapid.
Conform Apple Performance Guidelines, principalii factori care încetinesc randarea CALayer: ierarhia complexă de sublayers (peste 30 de straturi pe ecran), utilizarea măștilor (proprietatea mask), calculul automat al umbrei fără shadowPath, utilizarea excesivă a shouldRasterize pentru straturi dinamice.
Instrumentul Core Animation Instrument din XCode permite monitorizarea timpului de randare al fiecărui strat, numărul de buffere offscreen și frecvența apelurilor drawRect. Timpul optim de randare pentru 60 FPS — nu mai mult de 8 ms pe CPU și 8 ms pe GPU.
Randarea Offscreen — randarea stratului într-un buffer intermediar înainte de afișarea pe ecran. Apare la utilizarea cornerRadius + masksToBounds cu conținut, opacitate de grup, măști și shouldRasterize. Fiecare trecere offscreen durează 2–5 ms, de aceea randările offscreen excesive sunt critice pentru performanță.
Pentru diagnosticarea randării offscreen utilizați instrumentul Color Offscreen-Rendered din Core Animation Instrument. Straturile galbene — offscreen, cele albastre — randare directă pe ecran. Minimizarea trecerilor offscreen este tehnica cheie de optimizare în iOS.
Primul exemplu demonstrează configurarea de bază a CALayer cu crearea de umbră, rotunjirea colțurilor și bordură. shadowPath este setat explicit pentru accelerarea randării:
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
}
Al doilea exemplu — animarea transform prin CABasicAnimation cu transformare 3D de perspectivă. Animația de rotație în jurul axei Y creează un efect de întoarcere a cărții:
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")
Al treilea exemplu — utilizarea CAGradientLayer pentru a crea un gradient de fundal. Gradientul este randat pe GPU și nu necesită resurse suplimentare la modificarea dimensiunilor:
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)
}
Întrebări frecvente
UIView — este un strat peste CALayer care adaugă procesarea atingerilor, Auto Layout și integrarea cu UIViewController. CALayer funcționează doar cu reprezentarea vizuală și animația, ceea ce îl face mai ușor și mai eficient pentru sarcini pur grafice.
Peste 40 de proprietăți, inclusiv position, bounds, frame, opacity, backgroundColor, cornerRadius, transform, shadowOffset, shadowRadius, borderWidth și borderColor. Animația pornește automat la modificarea proprietății în interiorul blocului de animație UIView.animate.
Stabiliți shadowPath — un contur explicit al umbrei sub formă de UIBezierPath. Fără shadowPath, Core Animation analizează canalul alfa al conținutului pentru a calcula forma umbrei, ceea ce necesită o trecere suplimentară. Cu shadowPath, umbra este randată ca o simplă figură geometrică fără analiza conținutului.
Implicit animation — animația automată la modificarea proprietății care poate fi animate a CALayer în afara blocului UIView.animate. Durata implicită — 0.25 secunde. Poate fi dezactivată prin CATransaction.setDisableActions(true) sau poate fi setată o durată proprie prin CATransaction.begin/commit.
CAShapeLayer este mai eficient când trebuie afișată o formă vectorială — linie, cerc, poligon, contur complex. Acesta randază calea pe GPU fără a crea un buffer raster separat. CALayer de bază este potrivit pentru zone dreptunghiulare cu fundal, bordură și umbră.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și