swiftui-patterns
SwiftUIのアーキテクチャパターンを提供し、`@Observable`を使ったステート管理、ビューの合成、ナビゲーション、パフォーマンス最適化など、モダンなiOS/macOS UI開発のベストプラクティスを網羅します。
description の原文を見る
SwiftUI 架构模式,使用 @Observable 进行状态管理,视图组合,导航,性能优化,以及现代 iOS/macOS UI 最佳实践。
SKILL.md 本文
SwiftUI パターン
Apple プラットフォーム向けの最新 SwiftUI パターン。宣言的で高性能なユーザーインターフェースの構築に対応しています。Observation フレームワーク、ビュー合成、型安全なナビゲーション、パフォーマンス最適化をカバーしています。
活性化するとき
- SwiftUI ビューの構築とステート管理時(
@State、@Observable、@Binding) NavigationStackでナビゲーションフローを設計するとき- ビューモデルとデータフローを構築するとき
- リストと複雑なレイアウトのレンダリングパフォーマンスを最適化するとき
- SwiftUI で環境値と依存注入を使用するとき
ステート管理
プロパティラッパーの選択
最適でシンプルなラッパーを選択してください:
| ラッパー | ユースケース |
|---|---|
@State | ビューローカルな値型(トグル、フォーム入力、Sheet 表示) |
@Binding | 親ビューの @State への双方向参照 |
@Observable クラス + @State | 複数のプロパティを持つ独自モデル |
@Observable クラス(ラッパーなし) | 親ビューから渡された読み取り専用参照 |
@Bindable | @Observable プロパティへの双方向バインディング |
@Environment | .environment() で注入された共有依存項目 |
@Observable ViewModel
@Observable(ObservableObject ではなく)を使用します。プロパティレベルの変更を追跡するため、SwiftUI は変更されたプロパティを読み取ったビューのみを再レンダリングします:
@Observable
final class ItemListViewModel {
private(set) var items: [Item] = []
private(set) var isLoading = false
var searchText = ""
private let repository: any ItemRepository
init(repository: any ItemRepository = DefaultItemRepository()) {
self.repository = repository
}
func load() async {
isLoading = true
defer { isLoading = false }
items = (try? await repository.fetchAll()) ?? []
}
}
ViewModel を使用するビュー
struct ItemListView: View {
@State private var viewModel: ItemListViewModel
init(viewModel: ItemListViewModel = ItemListViewModel()) {
_viewModel = State(initialValue: viewModel)
}
var body: some View {
List(viewModel.items) { item in
ItemRow(item: item)
}
.searchable(text: $viewModel.searchText)
.overlay { if viewModel.isLoading { ProgressView() } }
.task { await viewModel.load() }
}
}
環境注入
@EnvironmentObject を @Environment で置き換えます:
// Inject
ContentView()
.environment(authManager)
// Consume
struct ProfileView: View {
@Environment(AuthManager.self) private var auth
var body: some View {
Text(auth.currentUser?.name ?? "Guest")
}
}
ビュー合成
無効化を制限するためのサブビュー抽出
ビューを小規模で焦点を絞った構造体に分割します。ステートが変更されたとき、そのステートを読み取ったサブビューのみが再レンダリングされます:
struct OrderView: View {
@State private var viewModel = OrderViewModel()
var body: some View {
VStack {
OrderHeader(title: viewModel.title)
OrderItemList(items: viewModel.items)
OrderTotal(total: viewModel.total)
}
}
}
再利用可能なスタイリング用 ViewModifier
struct CardModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 12))
}
}
extension View {
func cardStyle() -> some View {
modifier(CardModifier())
}
}
ナビゲーション
型安全な NavigationStack
NavigationStack と NavigationPath を使用してプログラムによる型安全なルーティングを実装します:
@Observable
final class Router {
var path = NavigationPath()
func navigate(to destination: Destination) {
path.append(destination)
}
func popToRoot() {
path = NavigationPath()
}
}
enum Destination: Hashable {
case detail(Item.ID)
case settings
case profile(User.ID)
}
struct RootView: View {
@State private var router = Router()
var body: some View {
NavigationStack(path: $router.path) {
HomeView()
.navigationDestination(for: Destination.self) { dest in
switch dest {
case .detail(let id): ItemDetailView(itemID: id)
case .settings: SettingsView()
case .profile(let id): ProfileView(userID: id)
}
}
}
.environment(router)
}
}
パフォーマンス
大規模コレクション用の遅延コンテナ
LazyVStack と LazyHStack はビューが表示されるときのみ生成されます:
ScrollView {
LazyVStack(spacing: 8) {
ForEach(items) { item in
ItemRow(item: item)
}
}
}
安定した識別子
ForEach で常に安定した一意な ID を使用します。配列インデックスの使用は避けてください:
// Identifiable 準拠または明示的な id を使用
ForEach(items, id: \.stableID) { item in
ItemRow(item: item)
}
body での高コスト操作を避ける
body内で I/O、ネットワーク呼び出し、高コスト計算を実行しないでください.task {}で非同期処理を処理します。ビューが消えるときに自動的にキャンセルされます- スクロールビューで
.sensoryFeedback()と.geometryGroup()の使用は慎重に行ってください - リスト内での
.shadow()、.blur()、.mask()の使用を最小限にしてください。画面外レンダリングをトリガーします
Equatable に準拠
body 計算が高コストなビューについて、Equatable に準拠して不要な再レンダリングをスキップします:
struct ExpensiveChartView: View, Equatable {
let dataPoints: [DataPoint] // DataPoint は Equatable に準拠する必要があります
static func == (lhs: Self, rhs: Self) -> Bool {
lhs.dataPoints == rhs.dataPoints
}
var body: some View {
// Complex chart rendering
}
}
プレビュー
#Preview マクロとインラインモックデータを使用して高速反復を行います:
#Preview("Empty state") {
ItemListView(viewModel: ItemListViewModel(repository: EmptyMockRepository()))
}
#Preview("Loaded") {
ItemListView(viewModel: ItemListViewModel(repository: PopulatedMockRepository()))
}
避けるべきアンチパターン
- 新しいコードで
ObservableObject/@Published/@StateObject/@EnvironmentObjectを使用しないでください。@Observableに移行してください - 非同期処理を
bodyやinitに直接配置しないでください。.task {}または明示的な読み込みメソッドを使用してください - データを所有しないサブビューでビューモデルを
@Stateとして作成しないでください。親ビューから渡してください - 型を消去するために
AnyViewを使用しないでください。条件付きビューについては@ViewBuilderまたはGroupを優先してください - Actor にデータを渡す際、または Actor からデータを受け取る際に
Sendable要件を無視しないでください
参考
スキル swift-actor-persistence を参照して、Actor ベースの永続化パターンを確認してください。
スキル swift-protocol-di-testing を参照して、プロトコルベースの DI と Swift Testing を使用したテストを確認してください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- affaan-m
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/affaan-m/everything-claude-code / ライセンス: MIT
関連スキル
nano-banana-2
inference.sh CLIを通じてGoogle Gemini 3.1 Flash Image Preview(Nano Banana 2)で画像を生成します。テキストから画像を生成する機能、画像編集、最大14枚の複数画像入力、Google Searchグラウンディング機能に対応しています。トリガーワード:「nano banana 2」「nanobanana 2」「gemini 3.1 flash image」「gemini 3 1 flash image preview」「google image generation」
octocode-slides
洗練されたマルチファイル形式のHTMLプレゼンテーションを生成します。6段階のフロー(概要 → リサーチ → アウトライン → デザイン → 実装 → レビュー)で構成されています。各スライドは独立したHTMLファイルとなり、iframeで読み込まれます。「スライドを作成してほしい」「プレゼンテーションを作ってほしい」「HTMLスライドを生成してほしい」「デックを構築してほしい」といった依頼や、ノート・ドキュメント・コードを洗練されたプレゼンテーションに変換する際に使用できます。
gpt-image2-ppt
OpenAIのgpt-image-2を使用して、視覚的に優れたPPTスライドを生成します。Spatial Glass、Tech Blue、Editorial Monoなど10種類のキュレーション済みスタイルに対応し、ユーザーが提供したPPTXファイルを模倣するテンプレートクローンモードも搭載しています。HTMLビューアと16:9形式のPPTXファイルを出力します。プレゼンテーション、スライド、ピッチデック、投資家向けPPT、雑誌風PPTの作成依頼などで活用してください。
nano-banana
Nano Banana PRO(Gemini 3 Pro Image)およびNano Banana(Gemini 2.5 Flash Image)を使用したAI画像生成機能です。以下の場合に活用できます:(1)テキストプロンプトからの画像生成、(2)既存画像の編集、(3)インフォグラフィックス、ロゴ、商品写真、ステッカーなどのプロフェッショナルなビジュアルアセット制作、(4)複数画像での人物キャラクターの一貫性保持、(5)正確なテキスト描画を含む画像生成、(6)AI生成ビジュアルが必要なあらゆるタスク。「画像を生成」「画像を作成」「写真を作る」「ロゴをデザイン」「インフォグラフィックスを作成」「AI画像」「nano banana」またはその他の画像生成リクエストをトリガーとして機能します。
oiloil-ui-ux-guide
モダンでクリーンなUI/UXガイダンス・レビュースキルです。新機能や既存システム(Webアプリ)に対して、実行可能なUI/UX改善提案、デザイン原則、デザインレビューチェックリストが必要な場合に活用できます。CRAP(コントラスト・反復・配置・近接)をベースに、タスクファーストなUX、情報設計、フィードバック・システムステータス、一貫性、affordances、エラー防止・復旧、認知負荷を重視します。モダンミニマルスタイル(クリーン・余白・タイポグラフィ主導)を強制し、不要なテキストを削減、アイコンとしての絵文字を禁止し、統一されたアイコンセットから直感的で洗練されたアイコンを推奨します。
axiom-hig-ref
Apple Human Interface Guidelines リファレンス — 色(セマンティックカラー、カスタムカラー、パターン)、背景(マテリアル階層、ダイナミック背景)、タイポグラフィ(標準スタイル、カスタムフォント、Dynamic Type)、SF Symbols(レンダリングモード、色、多言語対応)、ダークモード、アクセシビリティ、プラットフォーム固有の考慮事項を網羅したガイドラインです。