SwiftUI中如何保持原数据源与下游绑定同步并更新数据?
解决SwiftUI中编辑详情项同步更新原数据源的问题
你的问题核心在于Fruit是值类型,直接将fruit赋值给merchant.selection时会创建一份副本,详情页拿到的是独立的拷贝,修改它不会影响原数组中的元素。即便改成Binding类型,如果绑定的是这份副本,依然无法同步更新原数据源。
以下是两种可行的解决方案:
方法一:通过ID追踪选中项并创建绑定
步骤1:修正Fruit结构体
确保name为可变属性,且遵循Identifiable协议:
struct Fruit: Identifiable { let id = UUID() var name: String // 必须定义为var才能修改 }
步骤2:修改Merchant类
用选中项的ID替代直接存储Fruit实例,同时添加计算属性返回原数组中对应元素的绑定:
final class Merchant: ObservableObject { @Published var selection: Fruit.ID? // 存储选中水果的ID而非实例 @Published var fruits = [ Fruit(name: "Banana"), Fruit(name: "Apple") ] // 返回选中水果的绑定,供详情页使用 var selectedFruit: Binding<Fruit>? { guard let id = selection, let index = fruits.firstIndex(where: { $0.id == id }) else { return nil } return $fruits[index] } }
步骤3:更新FruitsView
点击按钮时存储选中项的ID,并通过计算属性传递绑定到详情页:
struct FruitsView: View { @EnvironmentObject var merchant: Merchant var body: some View { VStack { ForEach(merchant.fruits) { fruit in Button { merchant.selection = fruit.id } label: { Text(fruit.name) } .buttonStyle(.borderedProminent) } } .sheet(item: $merchant.selection) { _ in if let selectedFruit = merchant.selectedFruit { FruitDetailView(item: selectedFruit) } } } }
步骤4:修改FruitDetailView
接收Binding类型的item,修改时直接同步原数组:
struct FruitDetailView: View { @Binding var item: Fruit var body: some View { VStack { Text(item.name) Button("Press Me") { item.name = "Watermelon" // 此时修改会同步到原数据源 } } } }
方法二:直接传递数组元素的绑定
如果不想修改Merchant的selection类型,可以通过ForEach的绑定版本直接获取元素绑定:
修改FruitsView
struct FruitsView: View { @EnvironmentObject var merchant: Merchant var body: some View { VStack { // 遍历fruits的绑定数组,直接获取每个元素的Binding ForEach($merchant.fruits) { $fruit in Button { merchant.selection = fruit } label: { Text(fruit.name) } .buttonStyle(.borderedProminent) } } .sheet(item: $merchant.selection) { _ in // 根据选中项的ID找到原数组中的索引,创建绑定 if let index = merchant.fruits.firstIndex(where: { $0.id == merchant.selection?.id }) { FruitDetailView(item: $merchant.fruits[index]) } } } }
Fruit结构体和FruitDetailView的修改同方法一,此时点击修改按钮就能同步更新原数组中的水果名称。
内容的提问来源于stack exchange,提问作者bobby123uk
相关产品推荐
相关产品推荐

