CALayer はiOSのグラフィカルレイヤーの基底クラスで、QuartzCoreフレームワークの一部です。iOSの各UIViewには関連付けられたCALayerがあり、コンテンツのレンダリング、アニメーション、GPUコンポジションを処理します。Apple QuartzCore Documentation, 2025によると、CALayerは40以上のアニメーションプロパティをサポートし、Metalを通じて直接動作します。スムーズなアニメーションを作成し、インターフェースのパフォーマンスを最適化するには、CALayerの理解が不可欠です。
重要ポイント
CALayer はQuartzCoreフレームワークのクラスで、画面上の矩形領域のビットマップイメージを管理します。フレーム、backgroundColor、opacity、shadow、border、transformなどの視覚プロパティを格納します。UIViewとは異なり、CALayerはタッチイベントを処理せず、Auto Layoutに関与せず、ビューコントローラーのライフサイクルも持ちません。
アーキテクチャ的には、CALayerはCore Animationのコンテキストで Model パターンを実装しています。レイヤーは視覚プロパティの状態を保存し、Core Animationはアニメーション中の状態間の補間を管理します。この分離により、drawRectを介してコンテンツを再描画することなく、レイヤーのプロパティをアニメーション化できます。
Apple WWDC 2024 によると、CALayerはMetalを通じて動作するように書き直されました。最新のレンダリングパイプラインには3つの段階があります:Commit(CPUでのプロパティ更新)、Render(CPUでのGPUコマンド生成)、Composite(GPUでのコマンド実行)。CALayerは3つの段階すべてに参加し、それぞれにデータを提供します。
各レイヤーはsublayers(親の上にレンダリングされる子レイヤー)を含むことができます。レイヤー階層はUIViewの階層を反映していますが、それとは独立して存在できます。開発者は CALayer() を使用してUIViewから独立してレイヤーを作成し、addSublayerを介して階層に追加できます。
UIView はCALayerのラッパーであり、UIResponderを介したタッチ処理、Auto Layoutへの参加、storyboardでの表現、UIViewControllerとの統合を追加します。CALayer は軽量オブジェクトであり、純粋に視覚的な要素のためにUIViewなしで使用できます。
実際には、要素にタッチ処理やレイアウトが必要ない場合、CALayerとして実装できます。例えば、背景アニメーション、ローディングインジケーター、装飾要素などは、UIViewのオーバーヘッドを避けてCALayerを介してより効率的に実装できます。
基本プロパティ には、フレーム、配置、表示、視覚効果が含まれます。frameは親座標でのレイヤーの矩形領域を定義し、boundsは内部座標を定義し、positionはレイヤーの中心を定義します。positionの変更は、デフォルトで暗黙的アニメーションによってアニメーション化されます。
contents プロパティを使用すると、ビットマップコンテンツを直接設定できます(CGImageまたはCIImageを介して)。これはdrawRectによる描画の代替手段です。画像が既に準備できている場合、contentsに渡すだけで、Core Animationが追加処理なしでレンダリングします。
アニメーションには、CABasicAnimation、CAKeyframeAnimation、CATransition が使用されます。これらのクラスはすべてCALayerのプロパティキーパスを通じて動作し、positionからtransform.rotation.zまで、ほぼすべての属性をアニメーション化できます。
Apple は、特定のタスクを解決するためのいくつかの特殊なCALayerサブクラスを提供しています。基本のCALayerではなく適切なサブクラスを選択することで、ハードウェアアクセラレーションによる大幅なパフォーマンス向上が得られます。
CAReplicatorLayer は、コードの重複なしに繰り返しパターンを作成するのに特に便利です。例えば、10個のドットを持つローディングインジケーターは、instanceCount = 10とアニメーションタイムオフセットinstanceDelayを持つ1つのCAReplicatorLayerで実装できます。
CALayerのレンダリング は3つのフェーズで進行します。Commit — レイヤーのプロパティが変更されると、CPU上で変更バッチが形成されます。Render — Core Animationがレイヤーのプロパティに基づいてCPU上でMetalコマンドを生成します。Composite — GPUがコマンドを実行し、フレームを画面に出力します。プロセス全体はディスプレイのリフレッシュレートに同期されます。
複数レイヤーの コンポジション では、GPUが透明度、マスク、ブレンドモードを考慮して最終イメージに統合します。レイヤーがopaque = trueの場合、Core Animationはコンポジションを最適化し、アルファブレンディングの代わりに単純なピクセル置換を実行します。これにより大幅に高速化されます。
Apple Performance Guidelines によると、CALayerのレンダリングを遅くする主な要因は次のとおりです:複雑なsublayers階層(画面上に30層以上)、マスク(maskプロパティ)の使用、shadowPathなしの自動シャドウ計算、動的レイヤーへのshouldRasterizeの過剰な使用。
XCodeの Core Animation Instrument を使用すると、各レイヤーのレンダリング時間、オフスクリーンバッファ数、drawRect呼び出し頻度を監視できます。60 FPSの最適なレンダリング時間は、CPUで8 ms、GPUで8 msを超えません。
オフスクリーンレンダリング とは、画面に表示する前に中間バッファにレイヤーをレンダリングすることです。コンテンツを含むcornerRadius + masksToBounds、グループopacity、マスク、shouldRasterizeを使用する際に発生します。各オフスクリーンパスには2〜5 msかかるため、過剰なオフスクリーンレンダリングはパフォーマンスに深刻な影響を与えます。
オフスクリーンレンダリングを診断するには、Core Animation Instrumentの Color Offscreen-Rendered ツールを使用します。黄色のレイヤーはオフスクリーン、青色は直接画面レンダリングです。オフスクリーンパスを最小限に抑えることが、iOSにおける主要な最適化手法です。
最初の例は、シャドウ作成、角の丸め、境界線を含む基本的なCALayerの設定を示しています。レンダリングを高速化するために shadowPath が明示的に指定されています:
import UIKit
func configureLayer(_ view: UIView) {
let layer = view.layer
layer.cornerRadius = 16
layer.borderWidth = 2
layer.borderColor = UIColor.systemBlue.cgColor
layer.backgroundColor = UIColor.white.cgColor
layer.shadowColor = UIColor.black.cgColor
layer.shadowOpacity = 0.2
layer.shadowOffset = CGSize(width: 0, height: 4)
layer.shadowRadius = 8
layer.shadowPath = UIBezierPath(
roundedRect: view.bounds,
cornerRadius: layer.cornerRadius
).cgPath
}
2番目の例は、遠近感のある3D変換を伴うCABasicAnimationによるtransformアニメーションを示しています。Y軸回転アニメーションはカードを裏返す効果を生み出します:
let flipAnimation = CABasicAnimation(keyPath: "transform")
var transform = CATransform3DIdentity
transform.m34 = -1.0 / 500.0
transform = CATransform3DRotate(transform, .pi, 0, 1, 0)
flipAnimation.toValue = NSValue(caTransform3D: transform)
flipAnimation.duration = 0.8
flipAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
cardLayer.add(flipAnimation, forKey: "flip")
3番目の例は、背景グラデーションを作成するための CAGradientLayer の使用を示しています。グラデーションはGPUでレンダリングされ、サイズ変更時に追加のリソースを必要としません:
func addGradient(to view: UIView, colors: [UIColor]) {
let gradient = CAGradientLayer()
gradient.colors = colors.map { $0.cgColor }
gradient.locations = [0.0, 0.5, 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.frame = view.bounds
view.layer.insertSublayer(gradient, at: 0)
}
よくある質問
UIView はCALayerのラッパーであり、タッチ処理、Auto Layout、UIViewControllerとの統合を追加します。CALayerは視覚表現とアニメーションのみを扱うため、純粋にグラフィカルなタスクに対してより軽量で効率的です。
position、bounds、frame、opacity、backgroundColor、cornerRadius、transform、shadowOffset、shadowRadius、borderWidth、borderColor を含む40以上のプロパティがあります。UIView.animateブロック内でプロパティを変更すると、アニメーションが自動的に開始されます。
shadowPath を設定します — UIBezierPathとして明示的なシャドウの輪郭を指定します。shadowPathがない場合、Core Animationはシャドウの形状を計算するためにコンテンツのアルファチャンネルを分析するため、追加のパスが必要になります。shadowPathを使用すると、シャドウはコンテンツ分析なしで単純な幾何学的形状としてレンダリングされます。
暗黙的アニメーション は、UIView.animateブロックの外でCALayerのアニメーションプロパティを変更した際の自動アニメーションです。デフォルトの所要時間は0.25秒です。CATransaction.setDisableActions(true)で無効にするか、CATransaction.begin/commitでカスタム時間を設定できます。
CAShapeLayer は、線、円、多角形、複雑なパスなどのベクター形状を表示する必要がある場合により効率的です。個別のラスターバッファを作成せずに、GPU上でパスをレンダリングします。基本のCALayerは、背景、境界線、シャドウを持つ矩形領域に適しています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。