Core Animation: grunder, CALayer och animering i iOS

Författare: IT Sectr Publicerad: 2026-03-01 Lästid: 8 min

Core Animation är Apples lågnivåanimationsramverk som arbetar på CALayer-nivå och säkerställer rendering av innehåll på GPU. Core Animation är grunden för alla animationer i iOS och macOS: UIKit, AppKit, SceneKit och SpriteKit är byggda ovanpå det. Artikeln förklarar arkitekturen för CALayer, CABasicAnimation, CATransaction och praktiska tekniker.

Huvudpunkter

  • CALayer grundklassen i Core Animation för att hantera visning av innehåll på GPU
  • CABasicAnimation enkel animering av en CALayer-egenskap från fromValue till toValue
  • CATransaction gruppering av animationer i en transaktion med gemensam duration och completion
  • CAAnimation abstrakt basklass som CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup ärver från
  • Render server separat process (backboardd) som interpolerar animationsramar på GPU

Vad är Core Animation?

Core Animation är ett grafiskt ramverk från Apple som dök upp i Mac OS X 10.5 Leopard (2007) och portades till iOS från den första versionen av iPhone OS (2007). Core Animation hanterar komposition, animering och rendering av lager (CALayer) på GPU. Varje UIView i iOS har en inbyggd CALayer (view.layer) genom vilken all rendering sker.

Core Animation fungerar enligt principen för implicit animation: vissa ändringar av CALayer-egenskaper animeras automatiskt (animerar CABasicAnimation för position, bounds, opacity, backgroundColor). Implicit-animationer använder som standard CATransaction med en varaktighet på 0.25 sekunder och easeInOut-kurvan.

Enligt data från Apple WWDC 2024 bearbetar Core Animation upp till 120 FPS på ProMotion-enheter, med Metal för GPU-rendering. Storleken på ett typiskt lager i minnet är 4 byte per pixel (RGBA) + overhead ~100 byte per lager. Högst 1000 lager per skärm rekommenderas för stabila 60 FPS.

CALayer-arkitektur

CALayer grunden för Core Animation. Varje CALayer innehåller bitmappsinnehåll (eller en referens till en GPU-textur) och definierar geometri (bounds, position, anchorPoint, transform, cornerRadius, borderWidth, shadow). Lagret bearbetar inte beröringshändelser det ansvarar UIView/UIScrollView för. Lager bildar en hierarki (layer tree) som speglar vyhierarkin.

Core Animation stöder tre lagerträd: model layer tree (faktiska egenskaper), presentation layer tree (aktuell visning under animation) och render tree (data för GPU). Presentation layer används för att läsa mellanliggande animationsvärden i realtid.

Typer av CALayer

CALayer har specialiserade underklasser: CAShapeLayer (vektorgrafik), CAGradientLayer (gradient), CATextLayer (text), CATiledLayer (stora bilder uppdelade i brickor), CAEAGLLayer/MetalLayer (OpenGL/Metal). CAShapeLayer är populärast för anpassad animering tack vare stöd för CGPath och animering av strokeStart/strokeEnd.

CABasicAnimation grundläggande animering av egenskaper

CABasicAnimation är en underklass till CAAnimation som animerar en CALayer-egenskap från startvärdet (fromValue) till slutvärdet (toValue) eller relativ ändring (byValue). Animationen läggs till lagret via metoden layer.add(animation, forKey:) och utförs i render server utan appens deltagande på varje bildruta.

Nyckeln (keyPath) är en sträng som pekar på egenskapen: opacity, position, bounds, transform.rotation.z, cornerRadius, shadowOpacity etc. Core Animation stöder 60+ animerbara keyPath. För anpassade egenskaper används CATransaction och presentation layer.

swift
import QuartzCore

// CABasicAnimation för opacity och cornerRadius
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. Animering av genomskinlighet
    let fadeAnim = CABasicAnimation(keyPath: "opacity")
    fadeAnim.fromValue = 1.0
    fadeAnim.toValue = 0.2
    fadeAnim.duration = 2.0
    fadeAnim.autoreverses = true
    fadeAnim.repeatCount = .infinity

    // 2. Animering av avrundning av hörn
    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")
}

// Animering av position med ease-in-out
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 // uppdaterar model layer
}

Viktigt: CABasicAnimation är en tillfällig visning (presentation layer). Efter animationens slut återgår lagret till model layers ursprungliga värden. För att fixera slutläget, ställ in isRemovedOnCompletion = false, fillMode = .forwards och uppdatera model layer till slutvärdena.

CATransaction gruppering av animationer

CATransaction är en mekanism för att gruppera Core Animation-animationer i en enda transaktion. CATransaction.begin() och CATransaction.commit() definierar transaktionens gränser. Inuti transaktionen kan gemensamma parametrar ställas in: duration, timingFunction, completionBlock, disableActions. CATransaction är grunden för CALayers implicit-animationer.

Implicit animation fungerar när en CALayer-egenskap ändras utanför animationsblocket: layer.opacity = 0.5. Core Animation skapar automatiskt CABasicAnimation med duration från aktuell CATransaction (standard 0.25 s). För att inaktivera implicit-animation, använd CATransaction.setDisableActions(true).

swift
// CATransaction gruppering och slutförande
func groupedAnimation() {
    CATransaction.begin()
    CATransaction.setAnimationDuration(1.5)
    CATransaction.setAnimationTimingFunction(
        CAMediaTimingFunction(name: .easeOut)
    )
    CATransaction.setCompletionBlock {
        print("All animations completed")
    }

    // Alla ändringar inom transaktionen animeras med duration 1.5
    layer1.opacity = 0.3
    layer2.position = CGPoint(x: 200, y: 300)
    layer3.backgroundColor = UIColor.systemRed.cgColor

    CATransaction.commit()
}

// Inaktivering av implicit-animation
func updateWithoutAnimation() {
    CATransaction.begin()
    CATransaction.setDisableActions(true)
    layer.frame = newFrame // utan animering
    CATransaction.commit()
}

// Animering av CAShapeLayer-egenskaper
func animateProgress(percentage: CGFloat) {
    CATransaction.begin()
    CATransaction.setAnimationDuration(0.8)
    CATransaction.setCompletionBlock {
        print("Progress updated to (percentage)%")
    }
    progressLayer.strokeEnd = percentage / 100.0
    CATransaction.commit()
}

Kodexempel i Swift

Core Animation integreras med UIKit genom UIView-lagret. Exemplet nedan visar animering av CAShapeLayer en cirkulär förloppsindikator med animering av båglängd och rotation av lagret via CABasicAnimation.

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
        }
    }
}

CAShapeLayer animerar egenskapen strokeEnd från 0 till 1, vilket skapar effekten av att “fylla” den cirkulära förloppsindikatorn. CATransaction med varaktighet 0.6 och easeOut gör animationen mjuk. layer.lineCap = .round lägger till rundade linjeändar för ett snyggare utseende.

Vanliga frågor

Vad är skillnaden mellan Core Animation och UIView.animate?

Core Animation arbetar på CALayer-nivå och hanteras via CABasicAnimation, CATransaction. UIView.animate är ett högnivåomslag över Core Animation som automatiskt skapar CABasicAnimation för UIView-egenskaper. Core Animation ger mer kontroll: keyPath, timingFunction, fillMode, gruppering via CATransaction.

Vad är implicit animation i Core Animation?

Implicit animation är automatisk animering när en animerbar CALayer-egenskap ändras utanför animationsblocket. Till exempel skapar layer.opacity = 0.5 CABasicAnimation med varaktighet 0.25 s. Implicit-animationer hanteras via CATransaction och inaktiveras via setDisableActions(true).

Hur animerar man en anpassad CALayer-egenskap?

För anpassade egenskaper, implementera action(forKey:) i CALayer och returnera CAAnimation. Eller använd CALayer.display() för manuell rendering med animering via CADisplayLink. För egenskaper som stöder CABasicAnimation räcker det att ange keyPath som en sträng.

Varför är CALayer effektivare än UIView för animering?

CALayer är lättare än UIView: har inga händelsehanterare (touches, gester), deltar inte i Auto Layout och stöder inte accessibility. En typisk CALayer tar ~100 byte jämfört med ~300+ för UIView. Core Animation bearbetar lager i render server på GPU utan att blockera main thread.

Sammanfattning

  • Core Animation Apples lågnivåramverk för CALayer-animering med rendering på GPU
  • CALayer grundklass med 60+ animerbara egenskaper, stöder CAShapeLayer, CAGradientLayer, CATextLayer
  • CABasicAnimation animering av en egenskap med fromValue/toValue, tillagd via layer.add(animation, forKey:)
  • CATransaction gruppering av animationer med gemensam duration, timingFunction, completionBlock
  • Implicit animation automatisk animering vid ändring av CALayer-egenskaper (varaktighet 0.25 s)
  • Presentation layer lagrets aktuella tillstånd under animation, används för att läsa mellanliggande värden
  • Prestanda upp till 120 FPS på ProMotion, upp till 1000 lager vid 60 FPS, 4 byte/pixel

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också