--- name: swiftui-patterns description: SwiftUI 架構模式,涵蓋使用 @Observable 進行狀態管理、視圖組合、導航、效能優化以及現代 iOS/macOS UI 最佳實踐。 --- # SwiftUI 開發模式 (SwiftUI Patterns) 用於 Apple 平台建構聲明式、高性能用戶介面的現代 SwiftUI 模式。內容涵蓋 Observation 框架、視圖組合 (View Composition)、類型安全導航以及效能優化。 ## 何時啟用 - 編寫 SwiftUI View 並管理狀態 (`@State`, `@Observable`, `@Binding`)。 - 使用 `NavigationStack` 設計導航流程。 - 規劃 View Model 架構與數據流。 - 優化長列表 (Lists) 或複雜佈局的渲染效能。 - 在 SwiftUI 中使用環境值 (Environment Values) 與依賴注入。 ## 狀態管理 (State Management) ### 屬性包裝器 (Property Wrappers) 選用指南 | 包裝器 | 適用場景 | |---------|----------| | `@State` | View 本地數據(開關狀態、表單欄位、Sheet 顯示開關)。 | | `@Binding` | 對父視圖 `@State` 的雙向引用。 | | `@Observable` | 現代化的數據模型(ViewModel),僅在屬性變動時更新相關視圖。 | | `@Bindable` | 實現對 `@Observable` 屬性的雙向綁定。 | | `@Environment` | 跨層級共享的依賴項注入。 | ### 現代化 ViewModel (@Observable) 優先使用 `@Observable` 巨集而非舊有的 `ObservableObject`: ```swift @Observable final class ItemListViewModel { private(set) var items: [Item] = [] private(set) var isLoading = false var searchText = "" func load() async { isLoading = true defer { isLoading = false } // 執行非同步載入邏輯 } } ``` ## 視圖組合 (View Composition) - **精簡化視圖結構**:將大型視圖拆解為多個小型 Struct。當狀態變動時,SwiftUI 僅會重新渲染讀取該狀態的子視圖。 - **自定義 ViewModifier**:將重複的樣式邏輯封裝為修飾器,提升代碼複用率。 ## 導航架構 (Navigation) 使用 `NavigationStack` 結合 `NavigationPath` 實現類型安全且可程式化控制的路由系統。建議將路由邏輯收納於一個 `@Observable` 的 Router 類別中。 ## 效能優化 (Performance) - **延遲加載**:對於大型集合,使用 `LazyVStack` 或 `LazyHStack`。 - **穩定標識符**:在 `ForEach` 中務必使用穩定且唯一的 ID,避免使用陣列索引。 - **避免耗時運算**:嚴禁在 `body` 內執行 I/O、網路或大量運算。非同步任務請使用 `.task {}` 修飾器(它會在視圖消失時自動取消任務)。 - **Equatable 順應性**:對於渲染成本極高的視圖,實作 `Equatable` 以跳過不必要的重複渲染。 ## 應避免的反模式 - 在新專案中繼續使用 `ObservableObject` / `@Published` 等舊版 API。 - 使用 `AnyView` 類型抹除,應優先考慮 `@ViewBuilder`、`Group` 或 `switch`。 - 在 `body` 或 `init` 內直接發起非同步請求。 - 忽視跨 Actor 傳遞數據時的 `Sendable` 需求。