CAShapeLayer — その概念、プロパティ、図形の作成

著者: IT Sectr 公開日: 2026-06-12 読了時間: 10 分

CAShapeLayerは、GPU上でベクターパスをハードウェア加速レンダリングするために設計されたCALayerのサブクラスです。contentsを介してラスターイメージを扱う基本的なCALayerとは異なり、CAShapeLayerはオフスクリーンバッファを作成せずにCGPathを通じて定義された任意の図形をレンダリングします。Apple QuartzCore Documentation, 2025によると、CAShapeLayerはエッジのアンチエイリアシングにハードウェア加速を使用し、path、strokeStart、strokeEndのアニメーションをサポートしています。iOSでアイコン、進捗インジケータ、マスクを作成するための標準的なツールです。

重要なポイント

  • CAShapeLayer — CGPathを介してGPU上でベクターシェイプをレンダリングするためのCALayerのサブクラス。
  • パスのレンダリングは中間ラスターバッファを作成せずにハードウェアで行われます — Core Graphicsよりも高速です。
  • プロパティ fillColor、strokeColor、lineWidth、lineCap、lineJoinが図形の外観を制御します。
  • パスアニメーションにより、ある図形を別の図形に滑らかに変形できます — UIアニメーションの重要な機能です。
  • strokeStartstrokeEndをアニメーションしてパス描画効果を作成します — 読み込みインジケータに最適です。

CAShapeLayerとは?

CAShapeLayerは、iOS 3.0で導入されたベクターグラフィックスをレンダリングするための特殊なレイヤーです。ラスターイメージを保存するCALayerとは異なり、CAShapeLayerはパス(CGPath)の数学的記述を保存し、GPU上で直接レンダリングします。これにより、品質を損なうことなく図形を拡大縮小でき、内容を再描画せずにプロパティをアニメーションできます。

アーキテクチャ的には、CAShapeLayerはCALayerのすべての機能(シャドウ、ボーダー、トランスフォーム、マスク)を継承しています。さらに、パスを扱うための固有のプロパティを追加します:path、fillColor、strokeColor、lineWidth、lineCap、lineJoin、miterLimit、strokeStart、strokeEnd、fillRule。これらの各プロパティはCABasicAnimationを介してアニメーションできます。

Apple Documentationによると、CAShapeLayerはレンダリングにハードウェア加速を使用します。drawRect:でのCore Graphicsを介した描画(CPUがパスをラスターコンテキストにレンダリングする)とは異なり、CAShapeLayerはMetalを介してGPUに直接コマンドを送信します。結果として、特にアニメーション中により高いパフォーマンスが得られます。

CAShapeLayerは、ユーザーの操作に応じて形状が変化するインターフェース要素(進捗インジケータ、グラフ、タブバーアイコン、コンテンツ表示アニメーション用のマスク)に特に役立ちます。

CAShapeLayerがGPU上でパスをレンダリングする仕組み

CAShapeLayerのレンダリングプロセスは基本的なCALayerとは異なります。ピクセルを含むラスターバッファを保存する代わりに、CAShapeLayerはパスの頂点記述(点、ベジェ曲線、線分のセット)をGPUに渡します。GPUはこのパスを1パスでラスタライズし、フラグメントシェーダーステージで塗りつぶし色とストローク色を適用します。

このアプローチには2つの利点があります:品質を損なわない拡大縮小(ベクターグラフィックスは任意の解像度でシャープさを維持)と効率的なアニメーション(パスが変更されると、GPUは画面全体ではなく変更されたピクセルのみを再計算します)。

CAShapeLayerの主要プロパティ

path — CAShapeLayerの中心的なプロパティで、CGPathを受け取ります。パスには線、円弧、ベジェ曲線、長方形を含めることができます。SwiftではUIBezierPath、Core GraphicsではCGPathを介して作成されます。例:UIBezierPath(roundedRect: rect, cornerRadius: 16).cgPathは角丸長方形を作成します。

  • fillColor — 閉じたパスの塗りつぶし色(CGColor)。nilの場合は塗りつぶしなし。アニメーションをサポート。
  • strokeColor — パスのストローク色。lineWidthとともにアニメーションし、パス描画効果を生み出します。
  • lineWidth — ポイント単位のストローク線の太さ。デフォルトは1.0。アニメーション可能。
  • lineCap — 線の端のスタイル:.butt(まっすぐなカット)、.round(丸型)、.square(突き出た長方形)。
  • lineJoin — 線の結合スタイル:.miter(鋭角)、.round(丸型)、.bevel(面取り)。
  • strokeStartstrokeEnd — 0.0から1.0までのパスの描画割合。strokeEndをアニメーションすると段階的な表示効果が生まれます。
  • fillRule — 交差するパスの塗りつぶしルール:.nonZero(デフォルト)または.evenOdd。
  • miterLimit — lineJoin = .miterの場合の最大マイター長。無限に長い角を防ぎます。

lineDashPatternプロパティは破線を作成できます。数値の配列を受け取ります:[6, 3]は6ポイントのダッシュと3ポイントのギャップを意味します。lineDashPhaseはパターンオフセットを設定し、ダッシュ移動効果のためにアニメーションできます。

CAShapeLayer vs CALayer:それぞれを選ぶタイミング

CAShapeLayerと基本的なCALayerの選択は、コンテンツの種類によって異なります。要素が背景、ボーダー、シャドウを持つ長方形領域の場合、CALayerで十分です。要素が任意の形状を持ち、パスアニメーションや品質を損なわない拡大縮小が必要な場合、CAShapeLayerが適しています。

パフォーマンスも異なります。cornerRadiusとmasksToBoundsを持つCALayerは、コンテンツクリッピングのためにオフスクリーンバッファを作成し、フレームあたり2〜5ミリ秒追加します。CAShapeLayerはオフスクリーンバッファを必要としません — クリッピングは頂点シェーダーレベルで実行されます。複雑なマスクを持つ要素の場合、CAShapeLayerは2〜3倍高速になります。

  • CALayer:長方形要素、写真、ビデオ、角丸コンテンツ(cornerRadius)、シャドウ、ボーダー。
  • CAShapeLayer:アイコン、グラフ、プログレスバー、任意形状のマスク、アニメーションパス、表示アニメーションの図形。
  • CATextLayer:サブピクセルレンダリングとグリフキャッシュを必要とするテキスト。
  • CAGradientLayer:グラデーション塗りつぶし — マスクを介してCAShapeLayerと組み合わせてグラデーション付き図形を作成。

CAShapeLayerを他のレイヤーと組み合わせるのは一般的なパターンです。例えば、CAGradientLayerはCAShapeLayerをマスクとして使用し、グラデーション塗りつぶしの図形を作成します。このアプローチは、パフォーマンスを損なうことなくベクター品質とグラデーション塗りつぶしの両方を提供します。

CAShapeLayerのアニメーション:pathとstroke

パスアニメーションはCAShapeLayerの最も強力な機能の1つです。両方のパス(初期と最終)が同じ数の制御点とセグメントを持つ場合、Core Animationはそれらの間で滑らかな補間を実行します。結果として、ある図形から別の図形へのモーフィング効果が得られます。

パスの互換性条件:初期と最終のUIBezierPathは同じ構造を持つ必要があります — moveTo、addLine、addCurve、addQuadCurveの呼び出し数が一致する必要があります。構造が異なる場合、アニメーションは補間なしで瞬時に行われます。

Apple WWDC 2024によると、strokeStartとstrokeEndの組み合わせは最も一般的に使用されるCAShapeLayerアニメーションパターンです。strokeEndを0.0から1.0にアニメーションすると、パスの最初から最後までの描画効果が生まれます。これは読み込みインジケータ、グラフ表示アニメーション、カスタム画面遷移で使用されます。

パルス効果を作成するには、異なるタイミング関数でstrokeEndとopacityを同時にアニメーションします。動く破線効果の場合は、固定のlineDashPatternでlineDashPhaseをアニメーションします。両方のテクニックは、CPUの関与なしにCABasicAnimationを介して実装されます。

マスクとしてのアニメーション

CAShapeLayerは他のレイヤーのマスクとしてよく使用されます。例えば、コンテンツ表示アニメーションの場合:初期状態ではmask.pathはサイズゼロの長方形で、最終状態ではフルサイズです。Core Animationがパスを補間し、コンテンツが滑らかに表示されます。

このパターンは、iOSでのカード展開アニメーション、モーダルウィンドウの表示、ビューコントローラーのトランジションに使用されます。アルファアニメーションとは異なり、CAShapeLayerマスクアニメーションは任意の形状でより自然な表示効果を提供します。

SwiftでのCAShapeLayerコード例

最初の例 — strokeEndアニメーションを使用した円形進捗インジケータの作成。これはCAShapeLayerの主要機能を示す標準的なUI要素です:

swift
func createProgressIndicator(in view: UIView) -> CAShapeLayer {
    let circlePath = UIBezierPath(
        arcCenter: CGPoint(x: 50, y: 50),
        radius: 40,
        startAngle: -.pi / 2,
        endAngle: 3 * .pi / 2,
        clockwise: true
    )

    let trackLayer = CAShapeLayer()
    trackLayer.path = circlePath.cgPath
    trackLayer.strokeColor = UIColor.systemGray5.cgColor
    trackLayer.fillColor = nil
    trackLayer.lineWidth = 8
    view.layer.addSublayer(trackLayer)

    let progressLayer = CAShapeLayer()
    progressLayer.path = circlePath.cgPath
    progressLayer.strokeColor = UIColor.systemBlue.cgColor
    progressLayer.fillColor = nil
    progressLayer.lineWidth = 8
    progressLayer.lineCap = .round
    progressLayer.strokeEnd = 0
    view.layer.addSublayer(progressLayer)

    return progressLayer
}

// 75%にアニメーション
progressLayer.animateStrokeEnd(to: 0.75, duration: 1.5)

2番目の例 — 円と正方形の間のモーフィングアニメーション。両方のUIBezierPathは互換性のある構造を持っています:

swift
let morphLayer = CAShapeLayer()
morphLayer.fillColor = UIColor.systemPurple.cgColor
morphLayer.frame = rect

let circlePath = UIBezierPath(roundedRect: rect, cornerRadius: rect.width / 2)
let squarePath = UIBezierPath(roundedRect: rect, cornerRadius: 0)
morphLayer.path = circlePath.cgPath

let morphAnimation = CABasicAnimation(keyPath: "path")
morphAnimation.toValue = squarePath.cgPath
morphAnimation.duration = 0.6
morphAnimation.autoreverses = true
morphAnimation.repeatCount = .infinity
morphLayer.add(morphAnimation, forKey: "morph")

3番目の例 — コンテンツ表示アニメーション用のCAShapeLayerマスク。マスクは中心から端に向かって拡大します:

swift
func revealContent(_ view: UIView) {
    let maskLayer = CAShapeLayer()
    let size = view.bounds.size.width * 1.5
    let center = CGPoint(x: view.bounds.midX, y: view.bounds.midY)

    let initialPath = UIBezierPath(arcCenter: center, radius: 0, startAngle: 0, endAngle: .pi * 2, clockwise: true)
    let finalPath = UIBezierPath(arcCenter: center, radius: size, startAngle: 0, endAngle: .pi * 2, clockwise: true)

    maskLayer.path = initialPath.cgPath
    view.layer.mask = maskLayer

    let animation = CABasicAnimation(keyPath: "path")
    animation.toValue = finalPath.cgPath
    animation.duration = 0.4
    animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
    maskLayer.add(animation, forKey: "reveal")
    maskLayer.path = finalPath.cgPath
}

よくある質問

CAShapeLayerはdrawRectでの描画とどう違いますか?

drawRectはラスターコンテキストにレンダリングするためにCPUを使用します — これはアニメーションには低速です。CAShapeLayerはGPU上でパスをレンダリングし、path、strokeEnd、トランスフォームのアニメーション中に60 FPSを提供します。さらに、CAShapeLayerはサイズ変更時に再描画を必要としません — 図形はベクターとして拡大縮小されます。

パスアニメーションがスムーズに動作しないのはなぜですか?

スムーズなパスアニメーションには、初期と最終のUIBezierPathが同一の構造を持つ必要があります。moveTo、addLine、addCurveの呼び出し数が一致する必要があります。初期と最終の図形には同じセグメント数のUIBezierPathを使用してください。

CAShapeLayerで破線を作成するには?

lineDashPatternを設定します — ダッシュとギャップの長さを交互に指定する数値の配列。例えば、[8, 4]は8ptのダッシュと4ptのギャップを作成します。動く破線効果の場合は、線形タイミング関数でCABasicAnimationを介してlineDashPhaseをアニメーションします。

CAShapeLayerをマスクとして使用できますか?

はい、これは主要な使用例の1つです。CAGradientLayerや他のサブクラスを含む任意のCALayerのmaskプロパティにCAShapeLayerを割り当てます。マスクパスをアニメーションすると、任意の形状を通じたコンテンツのスムーズな表示効果が生まれます。

CAShapeLayerを介して図形をグラデーションで塗りつぶすには?

CAGradientLayerを作成し、そのmask = 目的のパスを持つCAShapeLayerに設定します。グラデーションはマスクパスの内側にのみ表示されます。このパターンはCAShapeLayerのベクター形状の利点とCAGradientLayerのグラデーション塗りつぶしを組み合わせます。

まとめ

  • CAShapeLayer — CGPathを介してGPU上でベクターパスをハードウェア加速レンダリングするためのCALayerのサブクラス。
  • 主要プロパティ:path、fillColor、strokeColor、lineWidth、lineCap、lineJoin、strokeStart、strokeEnd。
  • pathアニメーションは図形のモーフィングを作成 — 初期と最終のパスが同一構造である必要があります。
  • strokeEndアニメーション — 進捗インジケータとパス描画の標準パターン。
  • CAShapeLayerは、masksToBoundsを持つCALayerとは異なり、マスキングにオフスクリーンバッファを必要としません。
  • CAGradientLayerのマスクとして使用され、グラデーション塗りつぶしの図形を作成します。
  • 破線には、lineDashPhaseアニメーションとともにlineDashPatternを使用して動きの効果を出します。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

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

こちらもお読みください