---
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` 需求。
