如何从子视图更新核心数据实体?

时间:2020-11-10 06:35:45

标签: swift core-data swiftui

我有一个Thing核心数据实体和一个name字段。当我在[Thing]中显示List时,我希望能够在子视图中编辑name。这是实现此目的的代码,但感觉就像是糟糕的体系结构。 ThingView应该真正传递给thing,而不是thing.name

相反,我确实想将Thing传递给ThingView,但是如果我只是这样做,那么更新thing.name不会导致视图更新,因为Thing是引用类型。这里有关于清洁设计的想法吗?

struct ContentView: View {
  @ObservedObject var observableAllData: ObservableAllData
  var body: some View {
      NavigationView{List(observableAllData.allData.things.indices) { index in
        NavigationLink(destination:ThingView(
          thingName: $observableAllData.allData.things[index].name)) { 
            Text(observableAllData.allData.things[index].name)}
      }
    }
  }
}

struct ThingView: View {
  @Binding var thingName: String
  func updateThing() {
    thingName = "NEW"
  }
  var body: some View {
    VStack{
      Text(thingName)
      Button(action: updateThing) { Text("Update it!")}
    }
  }
}

编辑:澄清一下,我同时需要ThingViewContentView 单击“更新”进行更新。

1 个答案:

答案 0 :(得分:1)

您需要在ThingView个完整的Thing对象内部传递并在那里使用它而不是其属性。这样您就可以更新并保存。

所以

struct ThingView: View {
  @ObservedObject var thing: Thing

  func updateThing() {
    thing.name = "NEW"
    try? thing.managedObjectContext?.save()
  }
  var body: some View {
    VStack{
      Text(thing.name)
      Button(action: updateThing) { Text("Update it!")}
    }
  }
}

和链接

NavigationLink(destination:ThingView(
  thing: observableAllData.allData.things[index])) { 

更新:模式与所有依赖CoreData实体的情况相同,将其放在单独的视图中并使其观察到该实体。

在您的扩展问题中/什么不太礼貌;)/将行置于单独的视图中

struct ThingRowView: View {
  @ObservedObject var thing: Thing
   var body: some View {
      NavigationLink(destination:ThingView(thing: thing) { 
            Text(thing.name)}
      }
   }
}

并调用它

  NavigationView{List(observableAllData.allData.things.indices) { index in
     ThingRowView(thing: observableAllData.allData.things[index])
  }