CAAnimation — ключови понятия, CAAnimationGroup и анимации на слоеве

Автор: IT Sectr Публикувано: 2026-03-01 Време за четене: 8 мин

CAAnimation — абстрактен базов клас на Core Animation, който дефинира общ интерфейс за всички типове анимации: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition. Статията обяснява йерархията на класовете, ключовите свойства, групирането на анимации и практически примери в Swift.

Основни

  • CAAnimation — абстрактен базов клас на Core Animation, от който наследяват CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition
  • CAAnimationGroup — паралелно изпълнение на множество анимации с общ duration и timingFunction
  • CAKeyframeAnimation — анимация по ключови кадри с масиви от стойности и времеви отпечатъци
  • CAMediaTiming — протокол за управление на времето: duration, repeatCount, autoreverses, timeOffset
  • CATransition — предварително дефинирани преходи между състояния на слоя (fade, push, moveIn, reveal)

Какво е CAAnimation?

CAAnimation — абстрактен клас Core Animation, който дефинира общ интерфейс за всички анимации. Той имплементира протокола CAMediaTiming (време, повторение, автоматично връщане) и CAMediaTimingFillMode (поведение преди/след анимация). CAAnimation не може да бъде инстанцииран директно — използвайте един от подкласовете: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition или CAAnimation (чрез animationForKeyPath).

Всяка CAAnimation се добавя към CALayer чрез метода add(_:forKey:). Параметърът forKey е уникален идентификатор на анимацията върху слоя. Един и същ keyPath може да има само една активна анимация. За да замените анимация, използвайте removeAnimation(forKey:) преди добавяне на нова.

Според Apple, CAAnimation е временна промяна на слоя. След завършване на анимацията presentation layer се връща към стойностите на model layer, ако не са зададени fillMode и isRemovedOnCompletion.

Йерархия на класовете CAAnimation

Core Animation предоставя четири основни подкласа на CAAnimation, всеки за свой собствен сценарий на анимация. Разбирането на йерархията помага да изберете правилния тип за задачата.

КласПредназначениеКлючови характеристики
CABasicAnimationАнимация на едно свойство от A до BfromValue, toValue, byValue, keyPath
CAKeyframeAnimationАнимация по множество ключови кадриvalues, keyTimes, path, calculationMode
CAAnimationGroupГрупиране на множество анимациимасив animations, единен duration
CATransitionПреход между състояния на слояtype (fade/push/moveIn/reveal), subtype, startProgress

CABasicAnimation — най-простият и популярен подклас. CAKeyframeAnimation се използва за сложни траектории (напр. движение по крива на Безие). CAAnimationGroup стартира множество анимации паралелно. CATransition — готов преход между изображения или състояния на съдържание.

CAMediaTiming — управление на времето

Протоколът CAMediaTiming — фундаментална част от CAAnimation. Той дефинира основните времеви свойства: duration (продължителност), repeatCount (брой повторения), repeatDuration (обща продължителност на повторенията), autoreverses (връщане към началото), beginTime (начално време спрямо родителя), timeOffset (отместване в рамките на един цикъл), speed (скорост на възпроизвеждане).

Свойството fillMode (CAMediaTimingFillMode) определя показването на слоя преди (backwards) и след (forwards) анимация. Стойности: removed (по подразбиране — връщане към model layer), forwards (остава в крайно състояние), backwards (показва начално състояние преди старт), both (комбинира двете поведения). fillMode работи само с isRemovedOnCompletion = false.

CAAnimation наследява CAMediaTiming и може да бъде вложена в родителска анимация (CAAnimationGroup). В този случай beginTime се изчислява спрямо началото на родителя, а duration се ограничава от родителя. Speed = 2.0 ускорява анимацията два пъти.

CAAnimationGroup и CAKeyframeAnimation

CAAnimationGroup комбинира множество CAAnimation в една група. Всички дъщерни анимации стартират паралелно, ако не е зададено beginTime за всяка. Групата има свой собствен duration, който ограничава максималната продължителност на дъщерните анимации. timingFunction на групата се прилага като стойност по подразбиране, ако дъщерната анимация не е задала своя.

CAKeyframeAnimation анимира свойство през множество ключови кадри, дефинирани от масива values. Параметърът keyTimes (масив NSNumber от 0 до 1) определя времевите отпечатъци за всеки кадър. calculationMode определя интерполацията: linear, discrete (без интерполация), paced (равномерна скорост), cubic (сплайн), cubicPaced.

swift
import QuartzCore

// CAAnimationGroup — комбинация от анимации
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 — движение по траектория
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 с персонализирани стойности
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 // спрямо текущата позиция
    layer.add(bounce, forKey: nil)
}

CAAnimationGroup изпълнява fade, scale и rotate паралелно с duration 2.0. CAKeyframeAnimation с path и calculationMode = .cubicPaced осигурява равномерно движение по крива на Безие с автоматично завъртане (rotationMode = .auto). bounceAnimation използва isAdditive за относително отместване.

Примери за код в Swift

Пълен пример за CAAnimation за комплексна анимация на слой с използване на CATransition за смяна на съдържание и CAAnimationGroup за пулсация.

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 — преход между състояния
        let transition = CATransition()
        transition.type = .fade
        transition.duration = 0.5
        transition.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        demoLayer.add(transition, forKey: nil)

        // Променяме съдържанието чрез транзакция
        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 с type: .fade създава плавен преход между две състояния на backgroundColor. CAAnimationGroup комбинира scale, opacity и shadowOpacity за ефекта на пулсация. removeAllAnimations() нулира всички анимации и връща слоя към първоначалните стойности на model layer.

Често задавани въпроси

Каква е разликата между CABasicAnimation и CAKeyframeAnimation?

CABasicAnimation анимира свойство от начална (fromValue) до крайна (toValue) стойност с равномерна интерполация. CAKeyframeAnimation ви позволява да зададете масив от междинни стойности (values) и времеви отпечатъци (keyTimes) за нелинейна кадрова анимация, включително движение по крива чрез path.

Кога да използваме CAAnimationGroup?

CAAnimationGroup е необходим, когато множество анимации трябва да се изпълняват паралелно с гаранция за синхронизация: group duration ограничава всички дъщерни анимации. Използвайте групата за комбинирани ефекти: мащабиране + промяна на прозрачност + завъртане едновременно.

Какво е fillMode в CAAnimation?

fillMode определя показването на слоя преди (backwards) и след (forwards) анимация. Стойността .forwards оставя слоя в крайно състояние след завършване на анимацията (изисква isRemovedOnCompletion = false). .both комбинира backwards (начално състояние преди старт) и forwards.

Как да различим CAAnimation от CALayer анимация?

CAAnimation е обект на анимация (инструкция), който се добавя към CALayer чрез layer.add(animation, forKey:). Анимацията съществува като отделен обект, може да бъде използвана повторно (с копиране) и се управлява чрез CAMediaTiming. Слоят може да има множество анимации с различни ключове.

Резюме

  • CAAnimation — абстрактен базов клас на Core Animation с имплементация на CAMediaTiming и CAMediaTimingFillMode
  • Йерархия на класовете — CABasicAnimation (едно свойство), CAKeyframeAnimation (множество кадри), CAAnimationGroup (групиране), CATransition (преходи)
  • CAMediaTiming — протокол с duration, repeatCount, autoreverses, beginTime, timeOffset, speed, fillMode
  • CAAnimationGroup — паралелно изпълнение на анимации с единен duration и timingFunction
  • CAKeyframeAnimation — анимация чрез values/keyTimes или path (крива на Безие) с calculationMode
  • CATransition — предварително дефинирани типове: fade, push, moveIn, reveal с възможност за конфигуриране на subtype
  • Управление — layer.add(animation, forKey:), removeAnimation(forKey:), removeAllAnimations()

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също