CAAnimation — 핵심 개념, CAAnimationGroup 및 레이어 애니메이션

저자: IT Sectr 게시일: 2026-03-01 읽는 시간: 8 분

CAAnimation은 모든 애니메이션 유형(CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition)에 공통 인터페이스를 정의하는 Core Animation의 추상 기본 클래스입니다. 이 문서에서는 클래스 계층 구조, 주요 속성, 애니메이션 그룹화 및 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 프로토콜(duration, repeat, autoreverse) 및 CAMediaTimingFillMode(애니메이션 전/후 동작)를 구현합니다. CAAnimation은 직접 인스턴스화할 수 없습니다. 대신 하위 클래스 중 하나를 사용하세요: CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup, CATransition 또는 CAAnimation(animationForKeyPath를 통해).

각 CAAnimation은 add(_:forKey:) 메서드를 통해 CALayer에 추가됩니다. forKey 매개변수는 레이어의 고유 애니메이션 식별자입니다. 하나의 keyPath에는 하나의 활성 애니메이션만 있을 수 있습니다. 애니메이션을 교체하려면 새 애니메이션을 추가하기 전에 removeAnimation(forKey:)을 사용하세요.

Apple에 따르면 CAAnimation은 레이어의 "임시" 변경입니다. 애니메이션이 완료된 후 fillMode와 isRemovedOnCompletion이 설정되지 않은 경우 프레젠테이션 레이어는 모델 레이어 값으로 돌아갑니다.

CAAnimation 클래스 계층 구조

Core Animation은 4개의 주요 CAAnimation 하위 클래스를 제공하며, 각각 고유한 애니메이션 시나리오에 사용됩니다. 계층 구조를 이해하면 작업에 적합한 유형을 선택하는 데 도움이 됩니다.

클래스목적주요 기능
CABasicAnimation하나의 속성을 A에서 B로 애니메이션fromValue, 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(기본값 — 모델 레이어로 복귀), forwards(최종 상태 유지), backwards(시작 전 초기 상태 표시), both(두 동작 결합). fillMode는 isRemovedOnCompletion = false인 경우에만 작동합니다.

CAAnimation은 CAMediaTiming을 상속하며 상위 애니메이션(CAAnimationGroup)에 중첩될 수 있습니다. 이 경우 beginTime은 상위 시작을 기준으로 계산되고 duration은 상위 duration에 의해 제한됩니다. Speed = 2.0은 애니메이션 속도를 두 배로 높입니다.

CAAnimationGroup 및 CAKeyframeAnimation

CAAnimationGroup은 여러 CAAnimation 인스턴스를 하나의 그룹으로 결합합니다. 각각에 beginTime이 설정되지 않은 경우 모든 하위 애니메이션이 병렬로 시작됩니다. 그룹에는 자체 duration이 있으며, 이는 하위 애니메이션의 최대 기간을 제한합니다. 그룹의 timingFunction은 하위 애니메이션이 자체적으로 설정하지 않은 경우 기본값으로 사용됩니다.

CAKeyframeAnimation은 values 배열로 정의된 여러 키프레임에 걸쳐 속성을 애니메이션합니다. keyTimes 매개변수(0~1의 NSNumber 배열)는 각 프레임의 타임스탬프를 정의합니다. 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은 duration 2.0으로 fade, scale 및 rotate를 병렬 실행합니다. pathcalculationMode = .cubicPaced가 있는 CAKeyframeAnimation은 자동 회전(rotationMode = .auto)과 함께 베지어 곡선을 따른 균일한 이동을 제공합니다. bounceAnimation은 상대적 오프셋에 isAdditive를 사용합니다.

Swift 코드 예제

콘텐츠 전환에 CATransition을 사용하고 펄스 효과에 CAAnimationGroup을 사용하는 복잡한 레이어 애니메이션의 완전한 CAAnimation 예제입니다.

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

type: .fade의 CATransition은 두 backgroundColor 상태 간의 부드러운 전환을 만듭니다. CAAnimationGroup은 펄스 효과를 위해 scale, opacity 및 shadowOpacity를 결합합니다. removeAllAnimations()는 모든 애니메이션을 취소하고 레이어를 원래 모델 레이어 값으로 되돌립니다.

자주 묻는 질문

CABasicAnimation과 CAKeyframeAnimation의 차이점은 무엇인가요?

CABasicAnimation은 균일한 보간으로 속성을 초기값(fromValue)에서 최종값(toValue)으로 애니메이션합니다. CAKeyframeAnimation을 사용하면 비선형 키프레임 애니메이션을 위해 중간값(values) 및 타임스탬프(keyTimes) 배열을 지정할 수 있으며, path를 통한 곡선 기반 이동도 포함됩니다.

CAAnimationGroup은 언제 사용해야 하나요?

CAAnimationGroup은 여러 애니메이션이 동기화를 보장하며 병렬로 실행되어야 할 때 필요합니다. 그룹 duration은 모든 하위 애니메이션을 제한합니다. group을 사용하여 결합 효과(크기 조정 + 불투명도 변경 + 회전을 동시에)를 구현하세요.

CAAnimation에서 fillMode란 무엇인가요?

fillMode는 애니메이션 전(backwards) 및 후(forwards)의 레이어 표시를 결정합니다. .forwards 값은 애니메이션 완료 후 레이어를 최종 상태로 유지합니다(isRemovedOnCompletion = false 필요). .both는 backwards(시작 전 초기 상태)와 forwards를 결합합니다.

CAAnimation과 CALayer 애니메이션의 차이점은 무엇인가요?

CAAnimation은 layer.add(animation, forKey:)를 통해 CALayer에 추가되는 애니메이션 객체(명령)입니다. 애니메이션은 별도의 객체로 존재하며 재사용(복사) 가능하고 CAMediaTiming을 통해 관리됩니다. 하나의 레이어는 다른 키를 가진 여러 애니메이션을 가질 수 있습니다.

요약

  • CAAnimation — CAMediaTiming 및 CAMediaTimingFillMode를 구현하는 Core Animation의 추상 기본 클래스
  • 클래스 계층 구조 — CABasicAnimation(단일 속성), CAKeyframeAnimation(여러 프레임), CAAnimationGroup(그룹화), CATransition(전환)
  • CAMediaTiming — duration, repeatCount, autoreverses, beginTime, timeOffset, speed, fillMode를 포함한 프로토콜
  • CAAnimationGroup — 단일 duration 및 timingFunction으로 병렬 애니메이션 실행
  • CAKeyframeAnimation — calculationMode와 함께 values/keyTimes 또는 path(베지어 곡선)를 통한 애니메이션
  • CATransition — 미리 정의된 유형: fade, push, moveIn, reveal (subtype 구성 가능)
  • 관리 — layer.add(animation, forKey:), removeAnimation(forKey:), removeAllAnimations()

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기