Core Animation: alapok, CALayer és animáció iOS-ben

Szerző: IT Sectr Megjelenés: 2026-03-01 Olvasási idő: 8 perc

Core Animation az Apple alacsony szintű animációs keretrendszere, amely CALayer szinten működik és biztosítja a tartalom GPU-n történő megjelenítését. Core Animation az összes animáció alapja iOS és macOS rendszerben: UIKit, AppKit, SceneKit és SpriteKit erre épül. A cikk elmagyarázza a CALayer, CABasicAnimation, CATransaction architektúráját és a gyakorlati technikákat.

Főbb pontok

  • CALayer a Core Animation alaposztálya a tartalom GPU-n történő megjelenítésének kezelésére
  • CABasicAnimation egy CALayer tulajdonság egyszerű animációja fromValue-tól toValue-ig
  • CATransaction animációk csoportosítása egy tranzakcióba közös duration és completion paraméterekkel
  • CAAnimation absztrakt alaposztály, amelyből a CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup származik
  • Render server külön folyamat (backboardd), amely az animációs képkockákat interpolálja a GPU-n

Mi az a Core Animation?

Core Animation az Apple grafikus keretrendszere, amely a Mac OS X 10.5 Leopard (2007) jelent meg és az iPhone OS (2007) első verziójától kezdve iOS-re is portolták. Core Animation kezeli a rétegek (CALayer) kompozícióját, animációját és megjelenítését a GPU-n. Minden iOS UIView beépített CALayer-rel (view.layer) rendelkezik, amelyen keresztül a teljes megjelenítés történik.

Core Animation az implicit animation elve szerint működik: a CALayer tulajdonságok egyes változásai automatikusan animálódnak (CABasicAnimation-t animál position, bounds, opacity, backgroundColor számára). Az implicit-animációk alapértelmezés szerint CATransaction-t használnak 0.25 másodperces időtartammal és easeInOut görbével.

Az Apple WWDC 2024 adatai szerint a Core Animation akár 120 FPS-t is feldolgoz ProMotion eszközökön, a Metal-t használva GPU megjelenítéshez. Egy tipikus réteg memóriamérete 4 bájt pixelenként (RGBA) + ~100 bájt többlet rétegenként. Stabil 60 FPS-hez legfeljebb 1000 réteg ajánlott képernyőnként.

CALayer architektúra

CALayer a Core Animation alapja. Minden CALayer bitmap tartalmat (vagy GPU textúrára való hivatkozást) tartalmaz és meghatározza a geometriát (bounds, position, anchorPoint, transform, cornerRadius, borderWidth, shadow). A réteg nem dolgozza fel az érintési eseményeket erről a UIView/UIScrollView gondoskodik. A rétegek hierarchiát (layer tree) alkotnak, amely tükrözi a nézet hierarchiát.

Core Animation három rétegfát támogat: model layer tree (tényleges tulajdonságok), presentation layer tree(aktuális megjelenítés animáció közben) és render tree (adatok a GPU-nak). A presentation layer az animáció közbenső értékeinek valós idejű olvasására szolgál.

CALayer típusok

A CALayer specializált alosztályokkal rendelkezik: CAShapeLayer (vektor grafika), CAGradientLayer (gradiens), CATextLayer (szöveg), CATiledLayer (csempékre osztott nagy képek), CAEAGLLayer/MetalLayer (OpenGL/Metal). A CAShapeLayer a legnépszerűbb egyedi animációkhoz a CGPath támogatásának és a strokeStart/strokeEnd animációnak köszönhetően.

CABasicAnimation tulajdonságok alap animációja

CABasicAnimation a CAAnimation alosztálya, amely egy CALayer tulajdonságot animál a kezdeti értékről (fromValue) a végső értékre (toValue) vagy relatív változásra (byValue). Az animáció a layer.add(animation, forKey:) metódussal adható hozzá a réteghez, és a render server-ben hajtódik végre az alkalmazás minden képkockán történő részvétele nélkül.

A kulcs (keyPath) egy karakterlánc, amely a tulajdonságra mutat: opacity, position, bounds, transform.rotation.z, cornerRadius, shadowOpacity stb. Core Animation 60+ animálható keyPath-et támogat. Egyedi tulajdonságokhoz CATransaction és presentation layer használatos.

swift
import QuartzCore

// CABasicAnimation opacity és cornerRadius számára
func animateLayer() {
    let layer = CALayer()
    layer.frame = CGRect(x: 50, y: 50, width: 100, height: 100)
    layer.backgroundColor = UIColor.systemBlue.cgColor
    view.layer.addSublayer(layer)

    // 1. Átlátszóság animációja
    let fadeAnim = CABasicAnimation(keyPath: "opacity")
    fadeAnim.fromValue = 1.0
    fadeAnim.toValue = 0.2
    fadeAnim.duration = 2.0
    fadeAnim.autoreverses = true
    fadeAnim.repeatCount = .infinity

    // 2. Sarkok lekerekítésének animációja
    let cornerAnim = CABasicAnimation(keyPath: "cornerRadius")
    cornerAnim.fromValue = 0
    cornerAnim.toValue = 50
    cornerAnim.duration = 2.0
    cornerAnim.autoreverses = true
    cornerAnim.repeatCount = .infinity

    layer.add(fadeAnim, forKey: "fade")
    layer.add(cornerAnim, forKey: "corner")
}

// Position animáció ease-in-out-al
func moveLayer(_ layer: CALayer, to point: CGPoint) {
    let anim = CABasicAnimation(keyPath: "position")
    anim.fromValue = NSValue(cgPoint: layer.position)
    anim.toValue = NSValue(cgPoint: point)
    anim.duration = 0.6
    anim.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
    anim.isRemovedOnCompletion = false
    anim.fillMode = .forwards
    layer.add(anim, forKey: "move")
    layer.position = point // model layer frissítése
}

Fontos: CABasicAnimation ideiglenes megjelenítés (presentation layer). Az animáció befejezése után a réteg visszatér a model layer kezdeti értékeihez. A végső állapot rögzítéséhez állítsa be az isRemovedOnCompletion = false, fillMode = .forwards értékeket, és frissítse a model layer-t a végső értékekre.

CATransaction animációk csoportosítása

CATransaction a Core Animation animációk egyetlen tranzakcióba történő csoportosításának mechanizmusa. CATransaction.begin() és CATransaction.commit() határozza meg a tranzakció határait. A tranzakción belül közös paraméterek állíthatók be: duration, timingFunction, completionBlock, disableActions. CATransaction a CALayer implicit-animációinak alapja.

Implicit animation akkor működik, amikor a CALayer tulajdonság az animációs blokkon kívül változik: layer.opacity = 0.5. Core Animation automatikusan CABasicAnimation-t hoz létre az aktuális CATransaction duration értékével (alapértelmezés 0.25 mp). Az implicit-animáció kikapcsolásához használja a CATransaction.setDisableActions(true) parancsot.

swift
// CATransaction csoportosítás és befejezés
func groupedAnimation() {
    CATransaction.begin()
    CATransaction.setAnimationDuration(1.5)
    CATransaction.setAnimationTimingFunction(
        CAMediaTimingFunction(name: .easeOut)
    )
    CATransaction.setCompletionBlock {
        print("All animations completed")
    }

    // A tranzakción belüli összes változás 1.5 időtartammal animálódik
    layer1.opacity = 0.3
    layer2.position = CGPoint(x: 200, y: 300)
    layer3.backgroundColor = UIColor.systemRed.cgColor

    CATransaction.commit()
}

// Implicit-animáció kikapcsolása
func updateWithoutAnimation() {
    CATransaction.begin()
    CATransaction.setDisableActions(true)
    layer.frame = newFrame // animáció nélkül
    CATransaction.commit()
}

// CAShapeLayer tulajdonságok animációja
func animateProgress(percentage: CGFloat) {
    CATransaction.begin()
    CATransaction.setAnimationDuration(0.8)
    CATransaction.setCompletionBlock {
        print("Progress updated to (percentage)%")
    }
    progressLayer.strokeEnd = percentage / 100.0
    CATransaction.commit()
}

Kódpéldák Swift-ben

A Core Animation a UIView rétegen keresztül integrálódik a UIKit-kel. Az alábbi példa a CAShapeLayer animációját mutatja be egy kör alakú folyamatjelző sávot az ívhossz animációjával és a réteg forgatásával CABasicAnimation segítségével.

swift
import UIKit
import QuartzCore

class CircularProgressView: UIView {

    private let progressLayer = CAShapeLayer()

    override func layoutSubviews() {
        super.layoutSubviews()

        let path = UIBezierPath(
            arcCenter: CGPoint(x: bounds.midX, y: bounds.midY),
            radius: bounds.width / 2 - 10,
            startAngle: -.pi / 2,
            endAngle: 3 * .pi / 2,
            clockwise: true
        )

        progressLayer.path = path.cgPath
        progressLayer.strokeColor = UIColor.systemBlue.cgColor
        progressLayer.lineWidth = 8
        progressLayer.fillColor = nil
        progressLayer.strokeEnd = 0
        progressLayer.lineCap = .round
        layer.addSublayer(progressLayer)
    }

    func setProgress(_ value: CGFloat, animated: Bool = true) {
        if animated {
            CATransaction.begin()
            CATransaction.setAnimationDuration(0.6)
            CATransaction.setAnimationTimingFunction(
                CAMediaTimingFunction(name: .easeOut)
            )
            progressLayer.strokeEnd = min(max(value, 0), 1)
            CATransaction.commit()
        } else {
            progressLayer.strokeEnd = value
        }
    }
}

A CAShapeLayer a strokeEnd tulajdonságot animálja 0-ról 1-re, létrehozva a kör alakú folyamatjelző sáv „feltöltésének“ hatását. A 0.6 időtartamú és easeOut görbéjű CATransaction simává teszi az animációt. A layer.lineCap = .round lekerekített végeket ad a vonalnak a rendezettebb megjelenés érdekében.

Gyakran ismételt kérdések

Mi a különbség a Core Animation és a UIView.animate között?

Core Animation CALayer szinten működik és CABasicAnimation, CATransaction segítségével kezelhető. UIView.animate egy magas szintű burkoló a Core Animation felett, amely automatikusan CABasicAnimation-t hoz létre a UIView tulajdonságaihoz. Core Animation több vezérlést biztosít: keyPath, timingFunction, fillMode, csoportosítás CATransaction segítségével.

Mi az implicit animation a Core Animation-ben?

Implicit animation automatikus animáció, amikor a CALayer animálható tulajdonsága az animációs blokkon kívül változik. Például a layer.opacity = 0.5 CABasicAnimation-t hoz létre 0.25 mp időtartammal. Az implicit-animációk CATransaction segítségével kezelhetők és setDisableActions(true) segítségével kapcsolhatók ki.

Hogyan animálható egy egyedi CALayer tulajdonság?

Egyedi tulajdonságokhoz implementálja az action(forKey:) metódust a CALayer-ben és adjon vissza CAAnimation-t. Vagy használja a CALayer.display() metódust kézi megjelenítéshez CADisplayLink segítségével. A CABasicAnimation-t támogató tulajdonságoknál elegendő a keyPath megadása karakterláncként.

Miért hatékonyabb a CALayer, mint a UIView animációhoz?

CALayer könnyebb, mint a UIView: nincsenek eseménykezelői (touches, gesztusok), nem vesz részt az Auto Layout-ban és nem támogatja az accessibility-t. Egy tipikus CALayer ~100 bájtot foglal szemben a UIView ~300+ bájtjával. Core Animation a rétegeket a render server-ben dolgozza fel a GPU-n anélkül, hogy blokkolná a main thread-et.

Összefoglalás

  • Core Animation alacsony szintű Apple keretrendszer CALayer animációhoz GPU megjelenítéssel
  • CALayer alaposztály 60+ animálható tulajdonsággal, támogatja a CAShapeLayer, CAGradientLayer, CATextLayer elemeket
  • CABasicAnimation egy tulajdonság animációja fromValue/toValue paraméterekkel, layer.add(animation, forKey:) hozzáadva
  • CATransaction animációk csoportosítása közös duration, timingFunction, completionBlock paraméterekkel
  • Implicit animation automatikus animáció CALayer tulajdonságok változásakor (időtartam 0.25 mp)
  • Presentation layer a réteg aktuális állapota animáció közben, közbenső értékek olvasására használható
  • Teljesítmény akár 120 FPS ProMotion-on, akár 1000 réteg 60 FPS mellett, 4 bájt/pixel

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is