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プロトコル(duration、repeat、autoreverse)およびCAMediaTimingFillMode(アニメーション前後の動作)を実装しています。CAAnimationを直接インスタンス化することはできません。代わりにサブクラスのいずれかを使用します:CABasicAnimation、CAKeyframeAnimation、CAAnimationGroup、CATransition、またはCAAnimation(animationForKeyPath経由)。

各CAAnimationはadd(_:forKey:)メソッドを使用してCALayerに追加されます。forKeyパラメーターは、レイヤー上のアニメーションの一意の識別子です。1つのkeyPathには1つのアクティブなアニメーションしか持てません。アニメーションを置き換えるには、新しいものを追加する前にremoveAnimation(forKey:)を使用します。

Appleによると、CAAnimationはレイヤーの「一時的な」変更です。アニメーション完了後、fillModeとisRemovedOnCompletionが設定されていない場合、プレゼンテーションレイヤーはモデルレイヤーの値に戻ります。

CAAnimationクラス階層

Core Animationは4つの主要なCAAnimationサブクラスを提供しており、それぞれが独自のアニメーションシナリオに対応しています。階層を理解することで、タスクに適したタイプを選択できます。

クラス目的主要機能
CABasicAnimation1つのプロパティを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(1サイクル内のオフセット)、speed(再生速度)。

fillModeプロパティ(CAMediaTimingFillMode)は、アニメーション前(backwards)および後(forwards)のレイヤー表示を決定します。値:removed(デフォルト — モデルレイヤーに戻る)、forwards(最終状態を維持)、backwards(開始前に初期状態を表示)、both(両方の動作を組み合わせる)。fillModeはisRemovedOnCompletion = falseの場合にのみ機能します。

CAAnimationはCAMediaTimingを継承し、親アニメーション(CAAnimationGroup)にネストできます。この場合、beginTimeは親の開始を基準に計算され、durationは親のdurationによって制限されます。Speed = 2.0でアニメーション速度が2倍になります。

CAAnimationGroupとCAKeyframeAnimation

CAAnimationGroupは、複数のCAAnimationインスタンスを1つのグループに結合します。各アニメーションにbeginTimeが設定されていない限り、すべての子アニメーションは並列に開始されます。グループには独自のdurationがあり、子アニメーションの最大期間を制限します。グループのtimingFunctionは、子アニメーションが独自に設定しない場合のデフォルト値として使用されます。

CAKeyframeAnimationは、値の配列で定義された複数のキーフレームにわたってプロパティをアニメーションします。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は、2つのbackgroundColor状態間のスムーズなトランジションを作成します。CAAnimationGroupは、scale、opacity、shadowOpacityを組み合わせてパルス効果を実現します。removeAllAnimations()はすべてのアニメーションをキャンセルし、レイヤーを元のモデルレイヤー値に戻します。

よくある質問

CABasicAnimationとCAKeyframeAnimationの違いは?

CABasicAnimationは、均一な補間でプロパティを初期値(fromValue)から最終値(toValue)にアニメーションします。CAKeyframeAnimationでは、非線形キーフレームアニメーションのために中間値(values)とタイムスタンプ(keyTimes)の配列を指定でき、pathによる曲線ベースの移動も含みます。

CAAnimationGroupはいつ使うべき?

CAAnimationGroupは、複数のアニメーションを同期保証付きで並列実行する必要がある場合に必要です。グループのdurationがすべての子アニメーションを制限します。グループを使用して複合効果(拡大縮小+透明度変更+回転の同時実行)を実現します。

CAAnimationのfillModeとは?

fillModeは、アニメーション前(backwards)および後(forwards)のレイヤー表示を決定します。.forwardsはアニメーション完了後にレイヤーを最終状態に保ちます(isRemovedOnCompletion = falseが必要)。.bothはbackwards(開始前の初期状態)とforwardsを組み合わせます。

CAAnimationとCALayerアニメーションの違いは?

CAAnimationは、layer.add(animation, forKey:)を介してCALayerに追加されるアニメーションオブジェクト(命令)です。アニメーションは個別のオブジェクトとして存在し、再利用可能で(コピーして)、CAMediaTimingを通じて管理されます。1つのレイヤーは異なるキーを持つ複数のアニメーションを持つことができます。

まとめ

  • 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アプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください