在 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 中更灵活地管理和传递数据,从而实现更复杂的用户界面和交互。