swiftui-animation について
swiftui-animationは、SwiftUIで高度なアニメーションやMetalシェーダー効果を実装する開発者向けのガイダンススキルです。実装パターンに加え、モーション、アクセシビリティ、プラットフォーム、パフォーマンスに関する指針を扱います。
主な機能
- 01アニメーション曲線とスプリング
- 02ビュー遷移とマッチドジオメトリ
- 03PhaseAnimatorとKeyframeAnimator
- 04Metalシェーダーの統合
- 05モーションのアクセシビリティとプラットフォーム指針
- 06アニメーションのパフォーマンス指針
活用シーン
- 01複数段階のSwiftUIアニメーションを構築
- 02ビュー間のヒーロー遷移を作成
- 03GPUシェーダー効果を追加
- 04モーションのアクセシビリティと性能を確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ jamesrochabrun/ skills --skill swiftui-animationインストール後、Claude Code で/swiftui-animationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/animations.mdmetal-shaders.mdmotion-guidelines.mdtransitions.md詳細
SwiftUI アニメーションエキスパート
高度な SwiftUI アニメーションと Metal シェーダーの統合に関する専門的なガイダンスです。アニメーションカーブ、スプリング、トランジション、matched geometry effect、PhaseAnimator、KeyframeAnimator、GPU アクセラレーション対応のシェーダーエフェクトを扱います。
このスキルを使う場面
- モーションデザインの原則と、アニメーションを使うべき場面を理解する
- アニメーションをアクセシブルにし、プラットフォームに適したものにする
- SwiftUI でアニメーションを実装する(スプリング、イージング、キーフレーム)
- ビュートランジションを作成する(フェード、スライド、拡大縮小、カスタム)
- matchedGeometryEffect を使ってヒーローアニメーションを構築する
- Metal シェーダーを使って GPU アクセラレーション対応のエフェクトを追加する
- アニメーションのパフォーマンスを最適化する
- 複数フェーズのオーケストレーションされたアニメーションを作成する
クイックリファレンス
アニメーションの基本
// Explicit animation (preferred)
withAnimation(.spring(response: 0.4, dampingFraction: 0.75)) {
isExpanded.toggle()
}
// iOS 17+ spring presets
withAnimation(.snappy) { ... } // Fast, small bounce
withAnimation(.smooth) { ... } // Gentle, no bounce
withAnimation(.bouncy) { ... } // More bounce
よく使われるトランジション
// Basic
.transition(.opacity)
.transition(.scale)
.transition(.slide)
.transition(.move(edge: .bottom))
// Combined
.transition(.move(edge: .trailing).combined(with: .opacity))
// Asymmetric
.transition(.asymmetric(
insertion: .move(edge: .bottom),
removal: .opacity
))
Matched Geometry Effect
@Namespace var namespace
// Source view
ThumbnailView()
.matchedGeometryEffect(id: "hero", in: namespace)
// Destination view
DetailView()
.matchedGeometryEffect(id: "hero", in: namespace)
Metal シェーダーエフェクト(iOS 17+)
// Color manipulation
.colorEffect(ShaderLibrary.invert())
// Pixel displacement
.distortionEffect(
ShaderLibrary.wave(.float(time)),
maxSampleOffset: CGSize(width: 20, height: 20)
)
// Full layer access
.layerEffect(ShaderLibrary.blur(.float(radius)), maxSampleOffset: .zero)
リファレンスマテリアル
詳細なドキュメントは references/ にあります。
-
motion-guidelines.md - HIG のモーションデザイン原則
- 目的に基づくモーションの考え方
- アクセシビリティ要件
- プラットフォーム固有の考慮事項(iOS、visionOS、watchOS)
- 避けるべきアニメーションのアンチパターン
-
animations.md - アニメーション API の完全ガイド
- 暗黙的なアニメーションと明示的なアニメーション
- スプリングのパラメーターとプリセット
- アニメーションモディファイア(速度、遅延、繰り返し)
- 複数ステップのシーケンス向け PhaseAnimator
- プロパティごとのタイムライン向け KeyframeAnimator
- カスタムのアニメーション可能なプロパティ
-
transitions.md - ビュートランジションガイド
- 組み込みトランジション(不透明度、拡大縮小、スライド、移動)
- 組み合わせトランジションと非対称トランジション
- matched geometry effect の実装
- ヒーローアニメーションのパターン
- コンテンツトランジション(iOS 17+)
- カスタムトランジションの作成
-
metal-shaders.md - GPU シェーダー統合
- SwiftUI シェーダーモディファイア(colorEffect、distortionEffect、layerEffect)
- Metal シェーダー関数の記述
- UIViewRepresentable を使った MTKView の埋め込み
- クロスプラットフォームの Metal 統合(iOS/macOS)
- パフォーマンスに関する考慮事項
よく使われるパターン
展開可能なカード
struct ExpandableCard: View {
@State private var isExpanded = false
var body: some View {
VStack {
RoundedRectangle(cornerRadius: isExpanded ? 20 : 12)
.fill(.blue)
.frame(
width: isExpanded ? 300 : 150,
height: isExpanded ? 400 : 100
)
}
.onTapGesture {
withAnimation(.spring(response: 0.35, dampingFraction: 0.75)) {
isExpanded.toggle()
}
}
}
}
リスト項目の表示
ForEach(Array(items.enumerated()), id: \.element.id) { index, item in
ItemRow(item: item)
.transition(.asymmetric(
insertion: .move(edge: .trailing).combined(with: .opacity),
removal: .move(edge: .leading).combined(with: .opacity)
))
.animation(.spring().delay(Double(index) * 0.05), value: items)
}
脈動するインジケーター
Circle()
.fill(.blue)
.frame(width: 20, height: 20)
.scaleEffect(isPulsing ? 1.2 : 1.0)
.opacity(isPulsing ? 0.6 : 1.0)
.onAppear {
withAnimation(.easeInOut(duration: 1.0).repeatForever(autoreverses: true)) {
isPulsing = true
}
}
ベストプラクティス
- モーションには目的を持たせる - アニメーションを使うこと自体を目的にせず、体験を損なうことなくサポートするようにします
- モーションを任意にできるようにする - 触覚フィードバックや音声を補助的に使い、伝達手段としてモーションだけに頼らないでください
- 短くする - 短く正確なアニメーションは軽快に感じられ、情報を効果的に伝えます
- 明示的なアニメーションを優先する - 明確さを保つため、
.animation()モディファイアよりwithAnimationを使います - スプリングアニメーションを使う - より自然で iOS らしい印象になります
- まずは
.spring(response: 0.35, dampingFraction: 0.8)から始める - ほとんどの操作に適したデフォルト値です - アニメーションを 400ms 未満に保つ - それより長いと反応が鈍く感じられます
- モーションをキャンセルできるようにする - アニメーションが完了するまでユーザーを待たせないでください
- 実機でテストする - シミュレーターではアニメーションのタイミングが異なります
- シェーダーのパフォーマンスをプロファイルする - 複雑なエフェクトでは GPU の処理時間が重要です
トラブルシューティング
アニメーションが動作しない
- 状態の変更が
withAnimationで囲まれていることを確認します - プロパティがアニメーション可能か確認します
- ビューが実際に変更されていることを確認します
Matched geometry が跳ねる
- 両方のビューで同じ ID と namespace を使う必要があります
- 切り替え時には明示的に
withAnimationを使います - 適切なレイヤー順序になるよう
zIndexを確認します
シェーダーが表示されない
.metalファイルがターゲットに追加されていることを確認します- シェーダー関数のシグネチャが想定される形式と一致していることを確認します
- ディストーションエフェクトで
maxSampleOffsetが正しく設定されていることを確認します
コメント
Markdown 対応