CAAnimation — kluczowe pojęcia, CAAnimationGroup i animacje warstw

Autor: IT Sectr Opublikowano: 2026-03-01 Czas czytania: 8 min

CAAnimation — abstrakcyjna klasa bazowa Core Animation, definiująca wspólny interfejs dla wszystkich typów animacji: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition. Artykuł wyjaśnia hierarchię klas, kluczowe właściwości, grupowanie animacji i praktyczne przykłady w Swift.

Najważniejsze

  • CAAnimation — abstrakcyjna klasa bazowa Core Animation, po której dziedziczą CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition
  • CAAnimationGroup — równoległe wykonywanie wielu animacji ze wspólnym duration i timingFunction
  • CAKeyframeAnimation — animacja kluczowymi klatkami z tablicami wartości i znaczników czasowych
  • CAMediaTiming — protokół zarządzania czasem: duration, repeatCount, autoreverses, timeOffset
  • CATransition — predefiniowane przejścia między stanami warstwy (fade, push, moveIn, reveal)

Czym jest CAAnimation?

CAAnimation — abstrakcyjna klasa Core Animation, definiująca wspólny interfejs dla wszystkich animacji. Implementuje protokół CAMediaTiming (czas, powtórzenia, automatyczne odwrócenie) i CAMediaTimingFillMode (zachowanie przed/po animacji). CAAnimation nie może być instancjonowana bezpośrednio — użyj jednej z podklas: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition lub CAAnimation (przez animationForKeyPath).

Każda CAAnimation jest dodawana do CALayer przez metodę add(_:forKey:). Parametr forKey to unikalny identyfikator animacji na warstwie. Ten sam keyPath może mieć tylko jedną aktywną animację. Aby zastąpić animację, użyj removeAnimation(forKey:) przed dodaniem nowej.

Według Apple, CAAnimation to „tymczasowa” (temporary) zmiana warstwy. Po zakończeniu animacji presentation layer wraca do wartości model layer, jeśli nie ustawiono fillMode i isRemovedOnCompletion.

Hierarchia klas CAAnimation

Core Animation udostępnia cztery główne podklasy CAAnimation, każda dla swojego scenariusza animacji. Zrozumienie hierarchii pomaga wybrać odpowiedni typ dla zadania.

KlasaPrzeznaczenieKluczowe cechy
CABasicAnimationAnimacja jednej właściwości od A do BfromValue, toValue, byValue, keyPath
CAKeyframeAnimationAnimacja po kilku klatkach kluczowychvalues, keyTimes, path, calculationMode
CAAnimationGroupGrupowanie wielu animacjianimations tablica, jednolity duration
CATransitionPrzejście między stanami warstwytype (fade/push/moveIn/reveal), subtype, startProgress

CABasicAnimation — najprostsza i najpopularniejsza podklasa. CAKeyframeAnimation jest używana do złożonych trajektorii (np. ruch po krzywej Béziera). CAAnimationGroup uruchamia wiele animacji równolegle. CATransition — gotowe przejście między obrazami lub stanami zawartości.

CAMediaTiming — zarządzanie czasem

Protokół CAMediaTiming — fundamentalna część CAAnimation. Określa podstawowe właściwości czasowe: duration (czas trwania), repeatCount (liczba powtórzeń), repeatDuration (całkowity czas powtórzeń), autoreverses (powrót do początku), beginTime (czas startu względem rodzica), timeOffset (przesunięcie w obrębie jednego cyklu), speed (prędkość odtwarzania).

Właściwość fillMode (CAMediaTimingFillMode) określa wyświetlanie warstwy przed (backwards) i po (forwards) animacji. Wartości: removed (domyślnie — powrót do model layer), forwards (pozostaje w stanie końcowym), backwards (wyświetla stan początkowy przed startem), both (łączy oba zachowania). fillMode działa tylko gdy isRemovedOnCompletion = false.

CAAnimation dziedziczy CAMediaTiming i może być zagnieżdżona w animacji nadrzędnej (CAAnimationGroup). W tym przypadku beginTime jest obliczany względem początku rodzica, a duration jest ograniczone przez rodzicielskie. Speed = 2.0 przyspiesza animację dwukrotnie.

CAAnimationGroup i CAKeyframeAnimation

CAAnimationGroup łączy wiele CAAnimation w jedną grupę. Wszystkie animacje podrzędne uruchamiają się równolegle, jeśli nie ustawiono beginTime dla każdej. Grupa ma własny duration, który ogranicza maksymalny czas trwania animacji podrzędnych. timingFunction grupy jest stosowany jako wartość domyślna, jeśli animacja podrzędna nie ustawiła własnej.

CAKeyframeAnimation animuje właściwość przez wiele klatek kluczowych, określonych tablicą values. Parametr keyTimes (tablica NSNumber od 0 do 1) określa znaczniki czasowe dla każdej klatki. calculationMode określa interpolację: linear, discrete (bez interpolacji), paced (jednostajna prędkość), cubic (krzywa sklejana), cubicPaced.

swift
import QuartzCore

// CAAnimationGroup — kombinacja animacji
func complexLayerAnimation(_ layer: CALayer) {
    let fade = CABasicAnimation(keyPath: "opacity")
    fade.fromValue = 1.0
    fade.toValue = 0.3

    let scale = CABasicAnimation(keyPath: "transform.scale")
    scale.fromValue = 1.0
    scale.toValue = 1.5

    let rotate = CABasicAnimation(keyPath: "transform.rotation.z")
    rotate.fromValue = 0
    rotate.toValue = Double.pi * 2

    let group = CAAnimationGroup()
    group.animations = [fade, scale, rotate]
    group.duration = 2.0
    group.repeatCount = .infinity
    group.autoreverses = true

    layer.add(group, forKey: "pulse")
}

// CAKeyframeAnimation — ruch po trajektorii
func animateAlongPath(_ layer: CALayer) {
    let path = UIBezierPath()
    path.move(to: CGPoint(x: 0, y: 0))
    path.addCurve(
        to: CGPoint(x: 200, y: 300),
        controlPoint1: CGPoint(x: 100, y: 0),
        controlPoint2: CGPoint(x: 100, y: 300)
    )

    let anim = CAKeyframeAnimation(keyPath: "position")
    anim.path = path.cgPath
    anim.duration = 1.5
    anim.calculationMode = .cubicPaced
    anim.rotationMode = .auto
    anim.fillMode = .forwards
    anim.isRemovedOnCompletion = false

    layer.add(anim, forKey: "pathAnim")
    layer.position = CGPoint(x: 200, y: 300)
}

// CAKeyframeAnimation z niestandardowymi wartościami
func bounceAnimation(_ layer: CALayer) {
    let bounce = CAKeyframeAnimation(keyPath: "position.y")
    bounce.values = [0, -50, 0, -25, 0, -10, 0]
    bounce.keyTimes = [0, 0.15, 0.3, 0.45, 0.6, 0.8, 1.0]
    bounce.duration = 0.8
    bounce.timingFunction = CAMediaTimingFunction(name: .easeOut)
    bounce.isAdditive = true // względem bieżącej pozycji
    layer.add(bounce, forKey: nil)
}

CAAnimationGroup wykonuje fade, scale i rotate równolegle z duration 2.0. CAKeyframeAnimation z path i calculationMode = .cubicPaced zapewnia jednostajny ruch wzdłuż krzywej Béziera z automatycznym obrotem (rotationMode = .auto). bounceAnimation używa isAdditive do względnego przesunięcia.

Przykłady kodu w Swift

Pełny przykład CAAnimation dla złożonej animacji warstwy z użyciem CATransition do zmiany zawartości i CAAnimationGroup do pulsacji.

swift
import UIKit
import QuartzCore

class AnimationDemoView: UIView {

    private let demoLayer = CALayer()
    private var currentColor: CGColor = UIColor.systemBlue.cgColor

    override func layoutSubviews() {
        super.layoutSubviews()
        demoLayer.frame = CGRect(x: bounds.midX - 40, y: bounds.midY - 40,
                                 width: 80, height: 80)
        demoLayer.backgroundColor = currentColor
        demoLayer.cornerRadius = 12
        layer.addSublayer(demoLayer)
    }

    func animateTransition() {
        // CATransition — przejście między stanami
        let transition = CATransition()
        transition.type = .fade
        transition.duration = 0.5
        transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        demoLayer.add(transition, forKey: nil)

        // Zmieniamy zawartość przez transakcję
        currentColor = currentColor == UIColor.systemBlue.cgColor
            ? UIColor.systemRed.cgColor
            : UIColor.systemBlue.cgColor
        demoLayer.backgroundColor = currentColor
    }

    func startPulse() {
        let scaleUp = CABasicAnimation(keyPath: "transform.scale")
        scaleUp.fromValue = 1.0
        scaleUp.toValue = 1.3

        let fadeOut = CABasicAnimation(keyPath: "opacity")
        fadeOut.fromValue = 1.0
        fadeOut.toValue = 0.6

        let glow = CABasicAnimation(keyPath: "shadowOpacity")
        glow.fromValue = 0.0
        glow.toValue = 0.8

        let group = CAAnimationGroup()
        group.animations = [scaleUp, fadeOut, glow]
        group.duration = 1.2
        group.autoreverses = true
        group.repeatCount = .infinity
        group.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)

        demoLayer.add(group, forKey: "pulse")
    }

    func stopAnimations() {
        demoLayer.removeAllAnimations()
        demoLayer.transform = CATransform3DIdentity
        demoLayer.opacity = 1.0
        demoLayer.shadowOpacity = 0.0
    }
}

CATransition z type: .fade tworzy płynne przejście między dwoma stanami backgroundColor. CAAnimationGroup łączy scale, opacity i shadowOpacity dla efektu pulsacji. removeAllAnimations() resetuje wszystkie animacje i przywraca warstwę do początkowych wartości model layer.

Często zadawane pytania

Czym różni się CABasicAnimation od CAKeyframeAnimation?

CABasicAnimation animuje właściwość od wartości początkowej (fromValue) do końcowej (toValue) z jednostajną interpolacją. CAKeyframeAnimation pozwala określić tablicę wartości pośrednich (values) i znaczników czasowych (keyTimes) dla nieliniowej animacji klatkowej, w tym ruch po krzywej przez path.

Kiedy używać CAAnimationGroup?

CAAnimationGroup jest potrzebny, gdy wiele animacji ma być wykonywanych równolegle z gwarancją synchronizacji: grupowy duration ogranicza wszystkie animacje podrzędne. Używaj grupy do łącznych efektów: skalowanie + zmiana przezroczystości + obrót jednocześnie.

Czym jest fillMode w CAAnimation?

fillMode określa wyświetlanie warstwy przed (backwards) i po (forwards) animacji. Wartość .forwards pozostawia warstwę w stanie końcowym po zakończeniu animacji (wymaga isRemovedOnCompletion = false). .both łączy backwards (stan początkowy przed startem) i forwards.

Jak odróżnić CAAnimation od animacji CALayer?

CAAnimation — to obiekt animacji (instrukcja), który jest dodawany do CALayer przez layer.add(animation, forKey:). Animacja istnieje jako oddzielny obiekt, może być ponownie użyta (z kopiowaniem) i zarządzana przez CAMediaTiming. Warstwa może mieć wiele animacji z różnymi kluczami.

Podsumowanie

  • CAAnimation — abstrakcyjna klasa bazowa Core Animation z implementacją CAMediaTiming i CAMediaTimingFillMode
  • Hierarchia klas — CABasicAnimation (jedna właściwość), CAKeyframeAnimation (wiele klatek), CAAnimationGroup (grupowanie), CATransition (przejścia)
  • CAMediaTiming — protokół z duration, repeatCount, autoreverses, beginTime, timeOffset, speed, fillMode
  • CAAnimationGroup — równoległe wykonywanie animacji z jednolitym duration i timingFunction
  • CAKeyframeAnimation — animacja po values/keyTimes lub path (krzywa Béziera) z calculationMode
  • CATransition — predefiniowane typy: fade, push, moveIn, reveal z możliwością konfiguracji subtype
  • Zarządzanie — layer.add(animation, forKey:), removeAnimation(forKey:), removeAllAnimations()

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również