SwiftUI中@Bindable使用场景困惑:无需它父视图为何仍能更新
你猜的没错——类是引用类型,子视图拿到的和父视图是同一个实例。如果你的类已经遵循ObservableObject,且属性用@Published标记,修改子视图里的类属性时,ObservableObject的发布机制会自动通知所有关联视图刷新,这就是不用@Bindable父视图也能同步更新的原因。
那@Bindable到底什么时候用?核心是生成Binding对象,以下是具体场景:
子视图需要双向绑定到类的单个属性
比如你想在子视图里用TextField、Toggle这类需要Binding参数的控件,直接传普通的类实例是没法生成$前缀的绑定的。给类实例加上@Bindable后,就能通过$实例名.属性名拿到对应的Binding,实现双向绑定。
示例代码:// 遵循ObservableObject的类 class User: ObservableObject { @Published var name: String init(name: String) { self.name = name } } // 父视图 struct ParentView: View { @StateObject var user = User(name: "张三") var body: some View { VStack { Text("父视图显示:\(user.name)") ChildView(user: user) } } } // 子视图(必须用@Bindable才能生成Binding) struct ChildView: View { @Bindable var user: User var body: some View { TextField("修改名字", text: $user.name) .textFieldStyle(.roundedBorder) .padding() } }需要传递绑定到深层子视图
如果视图层级较深,要把类实例的绑定传递给下一级子视图,@Bindable能让你直接传递$实例名,不用手动创建Binding。下一级子视图同样用@Bindable接收,就能继续使用绑定能力。追踪类实例的替换操作
当父视图替换整个类实例(比如从服务器获取新数据后,把user换成新的User对象),@Bindable会自动感知实例变化,触发子视图刷新。如果只是用普通var接收实例,子视图可能不会响应这种实例替换操作。
注意:@Bindable不是用来替代ObservableObject的,它是在已有ObservableObject的基础上,给视图提供生成Binding的能力。如果类没遵循ObservableObject,就算加了@Bindable,修改属性也不会触发视图刷新。
内容的提问来源于stack exchange,提问作者Ting Qu

