SwiftUI @State 與 @Binding 基礎教學

SwiftUI 是資料驅動 (Data Driven) 的框架。當資料改變時,UI 會自動更新。要實現這一點,我們需要特定的屬性包裝器 (Property Wrappers) 來管理狀態。

@State (視圖內部狀態)

@State 用於儲存 View 內部的私有狀態。當 @State 變數的值改變時,SwiftUI 會銷毀並重新建立這個 View 的 body,從而更新畫面。

struct CounterView: View {
    @State private var count = 0 // 必須是 private,且給定初始值
    
    var body: some View {
        Button("點擊次數: \(count)") {
            count += 1 // 修改狀態,觸發畫面刷新
        }
    }
}
@State 應該只用於簡單的、屬於該 View 內部的資料 (如 Toggle 的開關、輸入框的文字)。

@Binding (雙向綁定)

當我們需要將狀態傳遞給子視圖 (Child View),並且希望子視圖能修改它時,就需要使用 @Binding@Binding 不會儲存資料,它只是對資料的引用 (Reference)

父視圖 (Parent)

struct ParentView: View {
    @State private var isPlaying = false // 真正的資料來源
    
    var body: some View {
        VStack {
            Text(isPlaying ? "播放中" : "暫停")
            
            // 傳遞 Binding (要在變數前加 $ 符號)
            PlayButton(isPlaying: $isPlaying)
        }
    }
}

子視圖 (Child)

struct PlayButton: View {
    @Binding var isPlaying: Bool // 這裡不用初始值,因為是引用
    
    var body: some View {
        Button(isPlaying ? "暫停" : "播放") {
            isPlaying.toggle() // 修改這裡的值,ParentView 的狀態也會跟著變
        }
    }
}

這就是 SwiftUI 資料流的基礎:Data flows down, Events flow up (資料向下傳遞,事件向上回饋)。@Binding 讓你實現了這一點。