Reputation: 9
I'm working on SwiftUI, With CoreData, I have Group.entity that can have many Items.entity.
Clicking on group navigates to a list of items in said group. you click the star to Toggle its fill, like with a "Favorites"
my system works 100% however to see the change i need to navigate BACK out and in again.
from my research - CoreData Objects work like observable objects, and FetchRequests are LIVE as in they tell a view that data has change and its time to refresh the LIST or the FOREACH.
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Group.entity(), sortDescriptors: [])
var groups: FetchedResults<Group>
@FetchRequest(entity: Item.entity(), sortDescriptors: [])
var items: FetchedResults<Item>
var body: some View {
NavigationView {
VStack {
AddDummyDataButton()
List {
ForEach(groups, id: \.self) { group in
NavigationLink(destination: GroupDetail(group: group)) {
Text(group.wrappedName)
}
}.onDelete { IndexSet in
let deleteItem = self.groups[IndexSet.first!]
self.moc.delete(deleteItem)
try? self.moc.save()
}
}
}
}
}
}
struct GroupDetail: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Group.entity(), sortDescriptors: [])
var groups: FetchedResults<Group>
@FetchRequest(entity: Item.entity(), sortDescriptors: [])
var itemsFetchedggr: FetchedResults<Item>
var group: Group
var body: some View {
List {
ForEach(self.group.itemsArray, id: \.self) { item in
HStack {
Text(item.wrappedName)
Image(systemName: item.isFave ? "star.fill" : "star")
.foregroundColor(.yellow)
.onTapGesture {
item.isFave.toggle()
try? self.moc.save()
}
}
}
}
}
}
Upvotes: 0
Views: 65
Reputation: 9
So - Calve off the Item into new struct for ItemRow - i guess this is best practice anyways, and use a for each to return the ItemRow passing in an Item.
this is pretty similar to the Landmarks Tutorial var item: Item
however we also need to make it :
@ObservedObject var item: Item.
I guess this is how swiftUI and CoreData are meant to work together, it took me ages to find a solution so i guess this will help someone in the future full code below
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Group.entity(), sortDescriptors: [])
var groups: FetchedResults<Group>
var body: some View {
NavigationView {
VStack {
AddDummyDataButton()
List {
ForEach(groups, id: \.self) { group in
NavigationLink(destination: GroupDetail(group:
group)) {
Text(group.wrappedName)
}
}.onDelete { IndexSet in
let deleteItem = self.groups[IndexSet.first!]
self.moc.delete(deleteItem)
try? self.moc.save()
}
}
}
}
}
}
struct GroupDetail: View {
@Environment(\.managedObjectContext) var moc
var group: Group
var body: some View {
List {
ForEach(self.group.itemsArray, id: \.self) { item in
ItemRow(item: item)
}
}
}
}
struct ItemRow: View {
@Environment(\.managedObjectContext) var moc
@ObservedObject var item: Item
var body: some View {
HStack {
Text(item.wrappedName)
Image(systemName: self.item.isFave ? "star.fill" : "star")
.foregroundColor(.yellow)
.onTapGesture {
self.item.isFave.toggle()
try? self.moc.save()
}
}
}
}
Upvotes: 1