Search code examples
swiftswiftuiswiftdata

SwiftUI view not updating when a child object is deleted from SwiftData


@Model
class Category: Decodable, Identifiable {
    var id: Int
    var title: String
    
    @Relationship var questions = [Question]()

}   

@Model
class Question: Decodable, Identifiable {
    var id: Int
    var text: String

    @Relationship var category: Category?

    init(id: Int, text: String) {
        self.id = id
        self.text = text
    }
    
}

struct EditCategoryView: View {
    @Environment(\.modelContext) private var modelContext
    @Bindable var category: Category //Bindable because I can also edit the category title on this screen

    var body: some View {
        ScrollView {
                        ForEach(category.questions) { question in
                            HStack {
                                Text(question.text)
                                    .baseTextStyle()
                                
                                Spacer()

                                Button(action: {
                                    delete(question: question)
                                }, label: {
                                    Text("Delete")
                                })
                            }
                            .padding(.horizontal, 8)
                        }
                    }
    }

    func delete(question: Question) {
        modelContext.delete(question)
        try! modelContext.save()
    }
}

Nothing happens visually when the Delete button is pressed. But if I leave the screen and come back, the deleted question will be gone. So the deletion is happening but category is not being observed for some reason.

How can I get the view to respond to the deletion of a Question object, which is a child of Category?


Solution

  • Till now the change doesn't reflect automatically.

    Though your shared code is not compilable, but you need to also manually remove from the array to show the changes immediately in the view.

        func delete(question: Question) {
            guard let index = category.questions.firstIndex(of: question) else {
                return
            }
            category.questions.remove(at: index)
            modelContext.delete(question)
            try! modelContext.save()
        }