web-dev-qa-db-fra.com

SwiftUI / CoreData / Master / Detail (avec édition) / Xcode 11 - Beta 5

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)
       }
   }
}
5
ShadowDES

Vous devez lier l'entité de DetailView à l'entité transmise par MasterView. Déclarez-le comme @Binding var entityName: EntityName

0
trapper

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
0
simibac