SwiftUI中从子视图更新独立类属性并触发父视图刷新的方法(Xcode12)
你用ObservableObject独立管理数据、父视图用@StateObject持有实例的整体思路是正确的,问题出在传参与子视图接收的类型不匹配:
- 你在ContentView中给ButtonView传递的
$data.title是Binding<String>类型,对应Data类中title属性的绑定 - 而ButtonView中声明的
@Binding var data: Data要求接收Binding<Data>类型,也就是整个Data类实例的绑定,两者类型完全不匹配,导致代码无法按预期运行。
下面提供两种可行的修正方案:
方案1:子视图接收整个ObservableObject实例
适合后续需要修改数据类多个属性的场景,修改点如下:
- ContentView传递Data实例时不需要加
$符号 - 子视图用
@ObservedObject接收ObservableObject实例
class Data: ObservableObject { @Published var title = "Title" } struct ContentView: View { @StateObject var data = Data() var body: some View { VStack { Text(data.title) .padding() // 直接传递Data类实例 ButtonView(data: data) } } } struct ButtonView: View { // 用@ObservedObject接收ObservableObject实例 @ObservedObject var data: Data var body: some View { Button(action: { data.title = "Hello" }, label: { Text("Button") }) } }
方案2:仅传递title属性的绑定
适合子视图只需要修改单个属性的轻量场景,修改点如下:
- 子视图直接声明String类型的Binding属性接收title
- ContentView继续传
$data.title即可
class Data: ObservableObject { @Published var title = "Title" } struct ContentView: View { @StateObject var data = Data() var body: some View { VStack { Text(data.title) .padding() // 传递title的Binding ButtonView(title: $data.title) } } } struct ButtonView: View { // 接收String类型的Binding @Binding var title: String var body: some View { Button(action: { title = "Hello" }, label: { Text("Button") }) } }
内容的提问来源于stack exchange,提问作者CoderZack
相关产品推荐
相关产品推荐

