Travailler sur un exemple d'application. Le but est d'avoir une liste tirée de CoreData dans un Master, puis de cliquer dessus pour accéder à un détail, où vous pouvez modifier les informations et les enregistrer. Lorsque vous modifiez le "nom" dans le détail, non seulement il met à jour le détail pour refléter le changement, mais il reflète également le changement sur le maître également. J'ai essayé de nombreuses façons d'y parvenir, mais jusqu'à présent, je n'ai pas trouvé de réponse.
// Code generation is turned OFF in the xcdatamodeld file
public class EntityName: NSManagedObject, Identifiable {
@NSManaged public var name: String
@NSManaged public var active: Bool
}
extension EntityName {
static func allEntityNameFetchRequest() -> NSFetchRequest<EntityName> {
let request: NSFetchRequest<EntityName> = EntityName.fetchRequest() as! NSFetchRequest<EntityName>
request.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
return request
}
}
struct MasterView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: EntityName.allEntityNameFetchRequest()) var allEntityNames: FetchedResults<EntityName>
var body: some View {
NavigationView {
List {
ForEach(self.allEntityNames) { entityName in
NavigationLink(destination: DetailView(entityName: entityName)) {
VStack(alignment: .leading) {
Text(entityName.name)
.font(.headline)
Text(String(entityName.active))
.font(.subheadline)
}
}
}
}
}
.onAppear() {
// Just want to populate the Core Data to have a few to work with
if self.allEntityNames.count == 0 {
for _ in 1...3 {
let newEntry = EntityName(context: self.managedObjectContext)
newEntry.name = "New Entry"
try! self.managedObjectContext.save()
}
}
}
}
}
struct DetailView: View {
var entityName = EntityName()
var body: some View {
VStack {
Text("Name: \(entityName.name)")
Text("Active: \(String(entityName.active))")
// What I'd like to do now:
//TextField("", text: $entityName.name)
//Toggle(isOn: $entityName.active)
}
}
}
Vous devez lier l'entité de DetailView à l'entité transmise par MasterView. Déclarez-le comme @Binding var entityName: EntityName
Comme l'a expliqué @trapper, le entityName
doit être lié au MasterView
.
Les mises à jour sont reflétées lorsque vous ajoutez @ObservedObject
dans le DetailView
comme suit:
@ObservedObject var entityName:EntityName