SwiftUI 綁定資料的 Binding 元件

SwiftUI 很多操作的元件都是綁定資料的 Binding 元件,比方 Toggle,TextField,Slider 等。binding 的中文是綁定的意思,binding 將綁定 view & model(資料),它們之間將實現雙向溝通的方便功能 :

  • 操作元件時將同步修改資料。
  • 當資料內容改變時,它也會同步更新元件。

接下來我們將使用 Toggle 開關控制是否下雨,認識 SwiftUI 的 binding 機制。

ps: 還不熟 State & Binding 的朋友可參考以下連結。

以 Toggle 開關控制是否下雨

struct ContentView: View {
@State private var isRain = true

var body: some View {
VStack {
Image(systemName: isRain ? "cloud.rain.fill" : "sun.max.fill")
.resizable()
.frame(width: 100, height: 100)
Text(isRain ? "我們淋著大雨不知何時才能放晴" : "太陽公公出來了,他對我呀笑呀笑")
Toggle("今天下雨嗎", isOn: $isRain)
}
}
}

我們希望 Toggle 開關可以親密地綁定 State 變數 isRain,滿足以下四種 case,讓畫面同步更新顯示正確的天氣 :

  • 開關打開時 isRain 自動變成 true。
  • 開關關閉時 isRain 自動變成 false。
  • isRain 設為 true 時開關自動打開。
  • isRain 設為 false 時開關自動關閉。

換句話說,我們希望利用 binding 綁定 toggle 跟 isRain。

SwiftUI 透過型別 Binding<Value> 的東西實現 binding 溝通機制,Value 代表綁定的資料型別。由於 Toggle 的狀態只有打開跟關閉兩種,所以它綁定的資料型別為 Bool,如下圖所示,我們輸入 Toggle 的程式時,參數 isOn 的型別為 Binding<Bool>。

因此,我們只要在剛剛的 isOn 參數傳入 isRain 的 binding,即可綁定 toggle & isRain。Swift 提供一個特別的語法,只要在 @State property 前加上 $,即可取得它的 binding,因此剛剛 Toggle 的程式變成

Toggle("今天下雨嗎", isOn: $isRain)

如果忘了加上 $,將出現紅色錯誤,因為它不是 Binding 型別。

執行 App

搭配 Binding 綁定資料的 SwiftUI 元件

SwiftUI 很多元件都像剛剛的 Toggle 一樣,利用 binding 綁定資料,比方以下 TextField,Slider,DatePicker 的例子。

  • TextField
  • Slider
  • DatePicker

我們在產生這些元件時,必須傳入 Binding 型別的資料變數,讓資料跟元件綁定,之後即可從變數方便地讀取內容,比方讀取 slider 的 value 或 text field 的文字。

其它 Binding 元件介紹

練習

One more thing: 自己產生 custom binding

剛剛在產生 Toggle 時,我們利用方便的 $ 取得 isRain 的 binding。也許有朋友好奇能不能自己產生 Binding ? 當然可以, 我們可以手動輸入 Binding( ),然後搭配參數 get & set。

我們想要建立 isRain 的 Binding,因此我們在參數 get 裡回傳 isRain,在 set 裡將參數 $0 存入 isRain。

Toggle(isOn: Binding(get: { isRain }, set: { isRain = $0 }), label: {
Text("今天下雨嗎?")
})

SwiftUI 產生 Binding 的各種方法

參考連結

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com