Core Animation: 기초, CALayer 및 iOS에서의 애니메이션

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

Core Animation은 CALayer 레벨에서 작동하고 GPU에서 콘텐츠를 렌더링하는 Apple의 저수준 애니메이션 프레임워크입니다. Core Animation은 iOS와 macOS에서 모든 애니메이션의 기반입니다: UIKit, AppKit, SceneKit, SpriteKit이 그 위에 구축되었습니다. 이 기사는 CALayer, CABasicAnimation, CATransaction의 아키텍처와 실용적인 기법을 설명합니다.

주요 포인트

  • CALayer — GPU에서 콘텐츠 표시를 관리하는 Core Animation의 기본 클래스
  • CABasicAnimation — fromValue부터 toValue까지의 하나의 CALayer 특성을 애니메이트하는 간단한 애니메이션
  • CATransaction — 공유 지속 시간과 완료를 가진 단일 트랜잭션으로 애니메이션 그룹화
  • CAAnimation — CABasicAnimation, CAKeyframeAnimation, CAAnimationGroup이 상속받는 추상 기본 클래스
  • Render server — GPU에서 애니메이션 프레임을 보간하는 별도 프로세스(backboardd)

Core Animation이란?

Core Animation은 Mac OS X 10.5 Leopard (2007)에서 도입되고 iPhone OS (2007)의 첫 버전에서 iOS로 포트된 Apple의 그래픽 프레임워크입니다. Core Animation은 GPU에서 레이어(CALayer)의 구성, 애니메이션 및 렌더링을 관리합니다. iOS의 각 UIView에는 내장 CALayer(view.layer)가 있어 모든 그림이 이를 통해 일어납니다.

Core Animation은 암시적 애니메이션의 원리로 작동합니다: 일부 CALayer 특성 변경이 자동으로 애니메이트됩니다(position, bounds, opacity, backgroundColor에 대한 CABasicAnimation). 암시적 애니메이션은 기본적으로 0.25초의 지속 시간과 easeInOut 곡선으로 CATransaction을 사용합니다.

Apple WWDC 2024에 따르면 Core Animation은 ProMotion 장치에서 최대 120 FPS를 처리하고, GPU 렌더링을 위해 Metal을 사용합니다. 일반적인 레이어의 메모리 풌트프린트는 픽셀당 4바이트(RGBA) + 레이어당 ~100바이트 오버헤드입니다. 안정적인 60 FPS를 위해 화면에 1000개 이하의 레이어가 권장됩니다.

CALayer 아키텍처

CALayer는 Core Animation의 기본입니다. 각 CALayer는 비트맵 콘텐츠(또는 GPU 텍스처 참조)를 포함하고 기하학(bounds, position, anchorPoint, transform, cornerRadius, borderWidth, shadow)을 정의합니다. 레이어는 터치 이벤트를 처리하지 않습니다 — UIView/UIScrollView가 처리합니다. 레이어는 뷰 계층구조를 반영하는 계층구조(layer tree)를 형성합니다.

Core Animation은 세 가지 레이어 트리를 유지합니다: model layer tree(실제 특성), presentation layer tree(애니메이션 중 현재 표시) 그리고 render tree(GPU 데이터). Presentation layer는 실시간 중간 애니메이션 값을 읽는 데 사용됩니다.

CALayer 유형

CALayer에는 전문 서브클래스가 있습니다: CAShapeLayer(벡터 그래픽), CAGradientLayer(그라디언트), CATextLayer(텍스트), CATiledLayer(타일로 나눈 큰 이미지), CAEAGLLayer/MetalLayer(OpenGL/Metal). CAShapeLayer는 CGPath 지원과 strokeStart/strokeEnd 애니메이션 때문에 커스텀 애니메이션에 가장 인기가 있습니다.

CABasicAnimation — 기본 특성 애니메이션

CABasicAnimation은 CAAnimation의 서브클래스로, 하나의 CALayer 특성을 시작 값(fromValue)에서 종료 값(toValue)까지 또는 상대적 변경(byValue)으로 애니메이트합니다. 애니메이션은 layer.add(animation, forKey:)를 통해 레이어에 추가되고 각 프레임에서 앱의 참여 없이 렌더 서버에서 실행됩니다.

키(keyPath)는 특성을 지정하는 문자열입니다: opacity, position, bounds, transform.rotation.z, cornerRadius, shadowOpacity 등. Core Animation은 60개 이상의 애니메이트 가능한 keyPath를 지원합니다. 커스텀 특성에 대해서는 CATransaction과 presentation layer가 사용됩니다.

swift
import QuartzCore

// opacity와 cornerRadius에 대한 CABasicAnimation
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. 투명도 애니메이션
    let fadeAnim = CABasicAnimation(keyPath: "opacity")
    fadeAnim.fromValue = 1.0
    fadeAnim.toValue = 0.2
    fadeAnim.duration = 2.0
    fadeAnim.autoreverses = true
    fadeAnim.repeatCount = .infinity

    // 2. 모나이 반지름 애니메이션
    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")
}

// ease-in-out으로 position 애니메이션
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 업데이트
}

중요: CABasicAnimation은 일시적인 표시(presentation layer)입니다. 애니메이션이 완료되면 레이어는 model layer 값으로 돌아갑니다. 최종 상태를 고정하려면 isRemovedOnCompletion = false, fillMode = .forwards를 설정하고 model layer를 최종 값으로 업데이트하십시오.

CATransaction — 애니메이션 그룹화

CATransaction은 Core Animation 애니메이션을 단일 트랜잭션으로 그룹화하는 메커니즘입니다. CATransaction.begin()과 CATransaction.commit()이 트랜잭션 경계를 정의합니다. 트랜잭션 내에서 공유 매개변수(duration, timingFunction, completionBlock, disableActions)를 설정할 수 있습니다. CATransaction은 CALayer 암시적 애니메이션의 기본입니다.

암시적 애니메이션은 CALayer 특성이 애니메이션 블록 밖에서 변경될 때 발생합니다: layer.opacity = 0.5. Core Animation은 현재 CATransaction(기본 0.25 s)의 지속 시간으로 CABasicAnimation을 자동 생성합니다. 암시적 애니메이션을 비활성화하려면 CATransaction.setDisableActions(true)를 사용하십시오.

swift
// CATransaction — 그룹화 및 완료
func groupedAnimation() {
    CATransaction.begin()
    CATransaction.setAnimationDuration(1.5)
    CATransaction.setAnimationTimingFunction(
        CAMediaTimingFunction(name: .easeOut)
    )
    CATransaction.setCompletionBlock {
        print("All animations completed")
    }

    // 트랜잭션 내의 모든 변경이 duration 1.5로 애니메이트됨
    layer1.opacity = 0.3
    layer2.position = CGPoint(x: 200, y: 300)
    layer3.backgroundColor = UIColor.systemRed.cgColor

    CATransaction.commit()
}

// 암시적 애니메이션 비활성화
func updateWithoutAnimation() {
    CATransaction.begin()
    CATransaction.setDisableActions(true)
    layer.frame = newFrame // 애니메이션 없음
    CATransaction.commit()
}

// CAShapeLayer 특성 애니메이트
func animateProgress(percentage: CGFloat) {
    CATransaction.begin()
    CATransaction.setAnimationDuration(0.8)
    CATransaction.setCompletionBlock {
        print("Progress updated to (percentage)%")
    }
    progressLayer.strokeEnd = percentage / 100.0
    CATransaction.commit()
}

Swift 코드 예제

Core Animation은 UIView 레이어를 통해 UIKit과 연결됩니다. 아래 예제는 CAShapeLayer 애니메이션을 보여줍니다 — 호의 길이 애니메이션과 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는 strokeEnd 특성을 0부터 1까지 애니메이트하여 원형 진행 “채우기” 효과를 만듭니다. 지속 시간 0.6과 easeOut이 있는 CATransaction은 애니메이션을 부드럽게 만듭니다. layer.lineCap = .round는 좌더 까끗한 시각을 위해 라인 끝을 동근리게 만듭니다.

자주 묻는 질문

Core Animation과 UIView.animate의 차이점은?

Core Animation은 CALayer 레벨에서 작동하고 CABasicAnimation과 CATransaction을 통해 제어합니다. UIView.animate는 Core Animation을 감싸는 고수준 래퍼로 UIView 특성에 대해 CABasicAnimation을 자동 생성합니다. Core Animation은 keyPath, timingFunction, fillMode, CATransaction을 통한 그룹화 등 더 많은 제어를 제공합니다.

Core Animation에서 암시적 애니메이션이란?

암시적 애니메이션은 애니메이트 가능한 CALayer 특성이 애니메이션 블록 밖에서 변경될 때 발생하는 자동 애니메이션입니다. 예를 들어 layer.opacity = 0.5는 0.25초 지속 시간의 CABasicAnimation을 생성합니다. 암시적 애니메이션은 CATransaction으로 관리되며 setDisableActions(true)를 사용하여 비활성화할 수 있습니다.

커스텀 CALayer 특성을 애니메이트하는 방법은?

커스텀 특성에 대해서는 CALayer에서 action(forKey:)을 구현하고 CAAnimation을 반환하십시오. 또는 CADisplayLink를 통한 애니메이션으로 수동 그림을 위해 CALayer.display()를 사용하십시오. CABasicAnimation을 지원하는 특성에 대해서는 keyPath를 문자열로 지정하기만 하면 됩니다.

애니메이션에서 CALayer가 UIView보다 효율적인 이유는?

CALayer는 UIView보다 가벍습니다: 이벤트 핸들러(touches, gestures)가 없고, Auto Layout에 참여하지 않으며, 접근성을 지원하지 않습니다. 일반적인 CALayer는 ~100바이트인 반면 UIView는 ~300+바이트입니다. Core Animation은 메인 스레드를 차단하지 않고 GPU에서 렌더 서버에서 레이어를 처리합니다.

요약

  • Core Animation — GPU 렌더링을 통한 CALayer 애니메이션을 위한 Apple의 저수준 프레임워크
  • CALayer — 60개 이상의 애니메이트 가능한 특성을 가진 기본 클래스, CAShapeLayer, CAGradientLayer, CATextLayer 지원
  • CABasicAnimation — fromValue/toValue로 단일 특성 애니메이션, layer.add(animation, forKey:)로 추가
  • CATransaction — 공유된 duration, timingFunction, completionBlock으로 애니메이션 그룹화
  • 암시적 애니메이션 — CALayer 특성 변경시 자동 애니메이션(지속 시간 0.25초)
  • Presentation layer — 애니메이션 중 현재 레이어 상태, 중간 값 읽는 데 사용
  • 성능 — ProMotion에서 최대 120 FPS, 60 FPS에서 최대 1000 레이어, 4바이트/픽셀

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

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

프로젝트 논의

더 읽어보기