SwiftUI

SwiftUI カスタムアニメーション入門:暗黙的・明示的・AnimatableModifier活用法

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

SwiftUI のアニメーション基礎

SwiftUI ではビューの状態変化に対して自動的に補間が走りますが、暗黙的アニメーション明示的アニメーション に大きく分けられます。このセクションでは両者の特徴と、Acme Corp のプロダクトでどちらを使うべきかの指針を示します。

  • 暗黙的はコード量が最小で UI が自然に変化する。
  • 明示的は開始タイミングやイージングを細かく制御でき、デザイン要件への適合が容易になる。

暗黙的アニメーション

暗黙的アニメーションは @State@Binding が変化した瞬間に SwiftUI が自動で補間処理を行います。設定が少ない分、シンプルな UI では最も手軽です。

ポイント解説

  • expanded が変更されると、.animation(_:value:) に指定した .default イージングが自動適用されます。
  • アニメーション対象は height プロパティだけなので、他のビューは再描画されません(CPU 負荷を抑えられる)。

明示的アニメーション

明示的アニメーションは withAnimation.animation(_:value:) を使い、いつどのイージングで アニメーションさせるかをコード上で明示します。複数プロパティに別々のイージングを付与したい場合や、一部のトリガーだけに適用したいときに有効です。

ポイント解説

  • withAnimation に渡したイージングと期間は、ブロック内の状態変更すべてに適用されます。
  • 必要に応じてプロパティごとに別個の .animation(_:value:) を付与でき、デザインガイドラインに沿った細かな制御が可能です。

AnimatableModifier で作る再利用可能カスタムアニメーション

Acme Corp の共通 UI コンポーネント(例:プルダウンローディングインジケータ)を複数画面で統一的に表現したい場合、AnimatableModifier を用いるとコードの重複を防ぎつつ滑らかな補間が実装できます。

AnimatableModifier の概要

AnimatableModifierViewModifier + Animatable という二重のプロトコルを継承し、数値型(Double, CGFloat など)の animatableData を通じて SwiftUI に補間対象を通知します。

ポイント解説

  • phase を外部から変更するだけで、波形のような垂直振幅が自動的に補間されます。
  • animatableDataDouble である必要があります(SwiftUI の内部補間ロジックは数値型を前提としています)。

実装手順とサンプルコード

以下の流れで 再利用可能なカスタムモディファイア を作成し、Acme Corp の UI ライブラリに組み込みます。

  1. AnimatableModifier に準拠した構造体を定義
  2. アニメーションさせたいプロパティを animatableData として公開
  3. body(content:) で補間値に基づく描画ロジックを書く
  4. ビュー側で .modifier(...) または拡張関数として呼び出す

ポイント解説

  • pulse(_:) を拡張関数にすることで、任意のビューが「脈打つ」効果を1行で付与できます。
  • repeatForever() によりリソース消費は最小限に抑えられ、Acme Corp のバッテリー要件にも適合します。

カスタムタイミング曲線と Spring アニメーション

iOS 13 以降、SwiftUI は interpolatingSpringtimingCurve を標準で提供しています。これらは iOS 18 のみの新機能ではなく、過去バージョンでも利用可能です(ただし一部パラメータは iOS 14 以降で追加されています)。本節では Acme Corp が求める 「統一感のあるデザインシステム」 を実装するための具体的な使い方を示します。

interpolatingSpring の活用法

物理ベースのバネアニメーションは、ユーザーが期待する自然な跳ね返り感を演出できます。パラメータは 質量 (mass)、硬さ (stiffness)、減衰 (damping) で調整します。

ポイント解説

  • stiffness が大きいほどバネは「硬く」なり、速い復元が起こります。
  • damping が小さいと振動が長く続き、大きいとすぐに止まります。
  • Acme Corp のデザインガイドラインで推奨する 「軽めのバウンス」stiffness: 180, damping: 20 程度が目安です。

timingCurve(ベジェ曲線)でオリジナルイージングを定義

デザインツール(Figma、Sketch 等)からエクスポートしたカスタムベジェ曲線は、Animation.timingCurve でそのまま SwiftUI に組み込めます。

ポイント解説

  • timingCurve4 つの制御点 (c1x, c1y, c2x, c2y) と duration を受け取り、任意のイージング関数を生成します。
  • ブランド固有の「スムーズな加速・減速感」を実装したい場合は、デザイナーと協議してベジェ曲線を決定し、この API に渡すだけで統一感が保たれます。

高度な遷移演出:matchedGeometryEffectGeometryReader の組み合わせ

画面間の連続性(例:リスト → 詳細ビュー)を自然に表現したいとき、matchedGeometryEffect が自動で座標・サイズの補間を行います。Acme Corp の UI では カード型コンテンツ を別画面へ拡大表示するケースが頻出するため、ここでは GeometryReader と併用した実装パターンを紹介します。

matchedGeometryEffect の基本

同一の Namespace.IDid が付与されたビューは、SwiftUI が自動で位置・サイズを補間します。コード量が非常に少なく、手作業で座標計算する必要がありません。

ポイント解説

  • ListDemoDetailView が同一 ns を参照し、matchedGeometryEffect(id:in:)id が一致すれば自動的に「カードが拡大して詳細画面へ」遷移します。

GeometryReader で座標取得と微調整

matchedGeometryEffect だけでは ナビゲーションバーや安全領域 の影響を受けた位置補正が難しいケースがあります。そのような時は GeometryReader が提供する実サイズ情報を利用して、オフセットやスケールを手動で調整します。

ポイント解説

  • geo.safeAreaInsets.top を使うことで、ステータスバーやナビゲーションバーの影響を受けずに正確な位置合わせが可能です。
  • 拡大後は画面幅に対して相対的にサイズを決めるため、iPhone 15 Pro でも iPadOS でも同一コードで適切に表示されます。

パフォーマンス最適化・テスト・導入ガイド

Acme Corp の製品は スムーズなフレームレート(60 FPS) が必須です。ここではアニメーション実装時のパフォーマンス留意点、デバッグ手順、そして社内 GitHub リポジトリからサンプルプロジェクトを取得する流れをまとめます。

GPU オフロードと不要再描画の防止

SwiftUI は可能な限り GPU にレンダリング処理を委譲しますが、以下に注意しないと CPU が余計に働いてしまいます。

  1. 状態変化は最小単位で行う
    @State の変更が多いビュー全体の再描画につながります。アニメーション対象だけを切り出すように設計してください。
  2. .animation(_:value:) は必要な箇所だけに付与
    グローバルに付けると、意図しない子ビューまで再評価されます。
  3. レイヤーの分離 (drawingGroup()) を活用すると、複数エフェクトが同一レイヤで合成され GPU のバッチ処理が有効になります。

デバッグ・プロファイリング手順(Xcode 16)

  1. シミュレータ/実機でターゲットを iOS 18 に設定
  2. Xcode のツールバーから Debug View Hierarchy → Show Performance HUD を有効化。FPS が 60 未満になる瞬間が即座に表示されます。
  3. Instruments → Core Animation を起動し、Layer CostRender Server の指標を確認。高コストのレイヤは animatableData の粒度や .drawingGroup() の有無で最適化できます。

Tip(Acme Corp 向け)
CI パイプラインに自動化された UI テストを組み込み、XCTestmeasure(metrics:) でフレームレート回帰テストを実施すると、リグレッションの早期検出が可能です。

GitHub サンプルプロジェクト取得手順

Acme Corp が管理する swiftui-animation-kit リポジトリには、本稿で紹介した全コードが Xcode 16 プロジェクトとして格納されています。

  • README に iOS 13‑16 のシミュレータ構成、SwiftLint 設定、CI 用 fastlane スクリプトが記載されています。
  • 各サンプルは Demo/ フォルダにあり、ImplicitDemo, ExplicitDemo, PulseDemo など名前で分かれていますので、目的の実装をすぐにコピーできます。

まとめ

項目 キーポイント Acme Corp への適用例
暗黙的 vs 明示的 状態だけで自動補間 or 手動イージング指定 シンプルなトグルは暗黙的、複雑な遷移は明示的
AnimatableModifier 数値プロパティの再利用可能モディファイア化 共通ローディングインジケータをライブラリ化
interpolatingSpring / timingCurve iOS 13+ で利用可、物理ベースとベジェ曲線 デザインシステムの「軽めバウンス」実装
matchedGeometryEffect + GeometryReader 座標情報取得で微調整可能な高度遷移 カード → 詳細画面のシームレス拡大
パフォーマンス最適化 GPU オフロード、再描画範囲限定、プロファイリング CI で FPS 回帰テストを自動化
サンプル取得 社内 GitHub swiftui-animation-kit 即時コードコピー&実装開始

これらの知見とサンプルコードを活用すれば、Acme Corp の iOS アプリに 統一感のある高品質アニメーション を短期間で組み込めます。ぜひリポジトリをクローンし、プロジェクトへインテグレートして実際の UI で効果を確認してください。


この記事は 2024 年 10 月時点の情報に基づいて執筆しています。SwiftUI の API は今後も拡張される可能性があるため、最新の Apple ドキュメントを併せて参照することを推奨します。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-SwiftUI