@Binding 用于在父子视图之间传递状态,实现双向数据绑定的属性包装器。父视图持有状态,而子视图使用绑定来修改该状态。这样可以避免状态重复并保持数据一致。
作用:@Binding用于在视图之间传递和共享可读写的值。它创建了一个对属性的引用,以便多个视图可以共享同一份数据,并且对数据的更改会在所有引用的地方生效。它做的事情是将值语义的属性“转换”为引用语义。对被声明为 @Binding 的属性进行赋值,改变的将不是属性本身,而是它的引用,这个改变将被向外传递,使用@state可以实现在当前view视图内的状态管理,但是如果需要将状态传递到子视图,并且实现双向绑定就需要使用@Binding来实现。
应用场景
- @Binding 主要用于与支持双向数据绑定的 UI 组件,如和 TextField、Stepper、Sheet 和 Slider 等配合使用。
- @Binding 适用于需要在子视图中直接修改父视图中的数据情况。
注意事项
- @Binding 不直接持有数据,而是提供了对其他数据源的读写访问的包装。
- @Binding允许 UI 元素直接修改数据,并反映这些数据的变化。
- 应当谨慎使用 @Binding,当子视图只需响应数据变化而无需修改时,无需使用 @Binding。
- 在复杂的视图层级中,逐级传递 @Binding 可能导致数据流难以追踪,此时应考虑使用其他状态管理方法。
- 确保 @Binding 的数据源是可信的,错误的数据源可能导致数据不一致或应用崩溃。由于 @Binding 只是一个管道,它并不保证对应的数据源在调用时必然存在。
- 开发者可以通过提供 get 和 set 的方式来自定义 Binding。
let binding = Binding<String>(
get: { text },
// 限制字符串的长度
set: { text = String($0.prefix(10)) }
)
使用示例
struct ParentView: View {
@State private var isOn = false
var body: some View {
ToggleView(isOn: $isOn)
}
}
struct ToggleView: View {
@Binding var isOn: Bool
var body: some View {
Toggle("Switch", isOn: $isOn)
}
}
在下面的示例中,父视图通过 @Binding 将布尔值传递给子视图,以控制子视图的可见性。
struct ParentView: View {
@State private var isChildViewVisible = false
var body: some View {
VStack {
Toggle(isOn: $isChildViewVisible) {
Text("Show Child View")
}
if isChildViewVisible {
ChildView(isVisible: $isChildViewVisible)
}
}
}
}
struct ChildView: View {
@Binding var isVisible: Bool
var body: some View {
Text("Child View")
Button(action: {
isVisible = false
}) {
Text("Hide")
}
}
}
网友评论