I am making a list app which supports multiple lists, where each list can have multiple items. (typical reminders app)
I believe I have written the code correctly for adding a new list, but I am not sure how to pass the list to the 'tasks' view - because when I add a new task to the list, it does not update the view. i.e. Although the item is actually getting added, it is not seen as the view is not refreshed. If I leave the view and come back, the added item is seen.
Do I use a @Binding or @State? How?
(if the below link is hidden with '*', it is tiny***)
Code for the view which shows all lists:
Code Block language swift struct TaskListView: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest(entity: TaskList().entity, sortDescriptors: [NSSortDescriptor(keyPath: \TaskList.name, ascending: true)]) private var lists: FetchedResults<TaskList> var body: some View { List { ForEach(lists, id: \.self) { list in NavigationLink(destination: TaskItemsView(list: list)) { Text(list.wrappedName) } } } .navigationBarItems(trailing: Button("Add") { withAnimation { addList() } }) .navigationTitle("Lists") } private func addList() { let newList = TaskList(context: viewContext) newList.name = "New List" newList.dateCreated = Date() let newTask = TaskItem(context: viewContext) newTask.name = "New List Task" newList.addToItems(newTask) try? viewContext.save() } }
Code for view that shows items in a list:
Code Block swift struct TaskItemsView: View { @Environment(\.managedObjectContext) var viewContext var list: TaskList var body: some View { List { ForEach(list.itemsArray, id: \.self) { item in Text(item.wrappedName) } } .navigationTitle(list.wrappedName) .navigationBarItems(trailing: Button("Add") { withAnimation { addTask() } }) } private func addTask() { let newTask = TaskItem(context: viewContext) newTask.name = "New Task in list \(list.wrappedName)" list.addToItems(newTask) try? viewContext.save() } }
i am assuming that you are describing this problem:
you tap the Add button inTaskItemsView
the addTask() function does indeed add a new Task to the list (var list: TaskList)
the TaskItemsView does not update
define the list variable as @ObservedObject var list: TaskList. this makes the TaskItemsView responsive to changes in Core Data attributes of the list.
after line 43 (list.addToItems(newTask)) add list.objectWillChange.send(). adding a new TaskItem to the list's NSSet of TaskItems is not seen as a change to a list attribute (its reference to the NSSet), so you need to signal a change to the list yourself.
DMG