在 SwiftUI 中,@Bindable
和 @Binding
是用於管理和傳遞資料的屬性包裝器。它們在 SwiftUI 的資料流和狀態管理中起著重要作用。
@Binding
@Binding
是一個屬性包裝器,用於在父檢視和子檢視之間共享資料。它允許子檢視讀取和寫入父檢視的狀態,而不需要直接持有該狀態的所有權。@Binding
通常用於在子檢視中修改父檢視的狀態。
示例
import SwiftUI
struct ParentView: View {
@State private var isOn: Bool = false
var body: some View {
VStack {
Toggle("Switch", isOn: $isOn)
ChildView(isOn: $isOn)
}
}
}
struct ChildView: View {
@Binding var isOn: Bool
var body: some View {
Toggle("Child Switch", isOn: $isOn)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
在這個示例中,ParentView
持有一個 @State
屬性 isOn
,並透過 $isOn
將其繫結傳遞給 ChildView
。ChildView
使用 @Binding
屬性包裝器來接收這個繫結,並可以在其內部修改 isOn
的值。
@Bindable
@Bindable
是一個較新的屬性包裝器,通常用於簡化和增強 @Binding
的功能。它允許你將整個物件作為繫結傳遞,而不僅僅是單個屬性。這在需要傳遞多個繫結屬性時特別有用。
示例
假設我們有一個模型類 User
,並希望在檢視中繫結多個屬性:
import SwiftUI
class User: ObservableObject {
@Published var name: String = ""
@Published var age: Int = 0
}
struct ParentView: View {
@StateObject private var user = User()
var body: some View {
VStack {
TextField("Name", text: $user.name)
Stepper("Age: \(user.age)", value: $user.age)
ChildView(user: user)
}
}
}
struct ChildView: View {
@Bindable var user: User
var body: some View {
VStack {
TextField("Child Name", text: $user.name)
Stepper("Child Age: \(user.age)", value: $user.age)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ParentView()
}
}
在這個示例中,ParentView
持有一個 @StateObject
屬性 user
,並將其傳遞給 ChildView
。ChildView
使用 @Bindable
屬性包裝器來接收整個 User
物件,並可以在其內部繫結和修改 User
的多個屬性。
總結
@Binding
:用於在父檢視和子檢視之間共享單個屬性的繫結。@Bindable
:用於在檢視之間共享整個物件的繫結,簡化了多個屬性的繫結傳遞。
透過使用 @Binding
和 @Bindable
,你可以在 SwiftUI 中更靈活地管理和傳遞資料,從而實現更復雜的使用者介面和互動。