SwiftUI パターン
Appleプラットフォーム向けのモダンなSwiftUIパターン。宣言的で高性能なユーザーインターフェースを構築するために使用する。Observationフレームワーク、ビュー合成、型安全なナビゲーション、パフォーマンス最適化をカバーする。
起動条件
- SwiftUIビューを構築し、状態を管理する場合(
@State、@Observable、@Binding) NavigationStackを使用したナビゲーションフローを設計する場合- ビューモデルとデータフローを構築する場合
- リストと複雑なレイアウトのレンダリングパフォーマンスを最適化する場合
- SwiftUIで環境値と依存性注入を使用する場合
状態管理
プロパティラッパーの選択
最も適したシンプルなラッパーを選択する:
@Observable ViewModel
ObservableObject ではなく @Observable を使用する——プロパティレベルの変更を追跡するため、SwiftUIは変更されたプロパティを読み取ったビューのみを再レンダリングする:
ViewModelを使用するビュー
環境への注入
@EnvironmentObject の代わりに @Environment を使用する:
ビュー合成
無効化を制限するためにサブビューを抽出する
ビューを小さく焦点を絞った構造体に分割する。状態が変化した場合、その状態を読み取ったサブビューのみが再レンダリングされる:
再利用可能なスタイルのための ViewModifier
ナビゲーション
型安全な NavigationStack
NavigationStack と NavigationPath を使用して、プログラム的で型安全なルーティングを実現する:
パフォーマンス
大規模なコレクションにレイジーコンテナを使用する
LazyVStack と LazyHStack はビューが表示される時のみ作成する:
安定した識別子
ForEach では常に安定した一意のIDを使用する——配列インデックスは避ける:
body 内での高コストな操作を避ける
body内でI/O、ネットワーク呼び出し、重い計算を絶対に実行しない- 非同期処理には
.task {}を使用する——ビューが消えると自動的にキャンセルされる - スクロールビューでは
.sensoryFeedback()と.geometryGroup()を慎重に使用する - リストでは
.shadow()、.blur()、.mask()の使用を最小化する——画面外レンダリングを引き起こす
Equatable に準拠する
bodyの計算が高コストなビューには、不要な再レンダリングをスキップするために Equatable に準拠する:
プレビュー
インラインのモックデータで #Preview マクロを使用して素早い反復を行う:
避けるべきアンチパターン
- 新しいコードで
ObservableObject/@Published/@StateObject/@EnvironmentObjectを使用する——@Observableに移行する bodyやinit内に直接非同期処理を置く——.task {}または明示的なロードメソッドを使用する- データを所有しないサブビューでViewModelを
@Stateとして作成する——代わりに親ビューから渡す AnyViewによる型消去を使用する——条件付きビューには@ViewBuilderまたはGroupを優先する- ActorとのデータのやりとりにおいてSendable要件を無視する
参照
Actorベースの永続化パターンについては、スキル swift-actor-persistence を参照。
プロトコルベースのDIとSwift Testingを使用したテストについては、スキル swift-protocol-di-testing を参照。


