code updated to reflect answer below. Would still love to skip $newName
and do something like TextField("New name...", text: $pcard.name)
but that throws an error.
long time searcher first time asker. StackOverflow has been invaluable.
Looking for some guidance on best practices to update single "rows" of a core data entity in a Detail View. Clearly I am going about this wrong because I can't get it to work, and there doesn't seem to be a lot of discussion out there about this specific seemingly simple use case.
My app has a standard MasterList/Detail structure, and I would like to bind updates made in the detail view to the entity that was fetched in the List View.
Code below, It's the passing/binding/updating part that I am interested in. Any help appreciated, either conceptually (here's how its designed to work) or practical (do it this way).
Thanks.
import SwiftUI
struct ListView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
entity: PCard.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \PCard.name, ascending: true)],
animation: .default
) private var pcards: FetchedResults<PCard>
var body: some View {
NavigationView {
List {
ForEach(pcards) { pcard in
NavigationLink(destination: DetailView(pcard: pcard)) {
Text(pcard.name ?? "no name specified")
}
}
}
.navigationTitle("My Cards")
}
}
}
struct DetailView: View {
@Environment(\.managedObjectContext) private var viewContext
@State private var newName: String = ""
@ObservedObject var pcard: PCard
var body: some View {
VStack {
Text(pcard.name ?? "no name specified").font(.largeTitle)
TextField("New name...", text: $newName).textFieldStyle(RoundedBorderTextFieldStyle())
Button(action: {
pcard.name = newName
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
}) {
//label
Label("Update", systemImage: "sparkles")
}
Spacer()
}
.padding()
}
}
struct ListView_Previews: PreviewProvider {
static var previews: some View {
ListView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
}