Home > other >  SwiftUI - CoreData - ForEach - Wrong Item gets deleted, Why?
SwiftUI - CoreData - ForEach - Wrong Item gets deleted, Why?

Time:08-30

I´ve got a list of Fetched Core Data Items, displayed as a NavigationLink inside a ForEach Loop. Each of those Elements can be deleted by Swipe or Context Menu. However when I add an additional confirmationDialog, and move the actual delete action into that one, the wrong item gets deleted (until the actual selected Item is the last one). Without the confirmationDialog, and the delete Action inside the Button, it works fine. Does anyone have any idea why?

Thank you!

import Foundation
import SwiftUI

struct IngredientsList: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(sortDescriptors: []) private var ingredients: FetchedResults<Ingredient>
    @State private var DeleteDialogue = false
    var body: some View {
            VStack{
                List{
    ForEach(ingredients){ingredients in
                        NavigationLink{
                            RecipeIngredientsDetailed(ingredients: ingredients, editMode: true, createmode: true)
                        } label: {
                            Text(ingredients.ingredientname ?? "")
                        }
                        .swipeActions(){
                            Button(role: .destructive){
                                DeleteDialogue = true
                            } label:{
                                Text("Delete")
                            }
                        }
                        .contextMenu(){
                            Button(role: .destructive){
                                DeleteDialogue = true
                            } label:{
                                Text("Delete")
                            }
                        }
                        .confirmationDialog("Are you sure?", isPresented: $DeleteDialogue){
                            Button("Delete Ingredient"){
                                viewContext.delete(ingredients)
                                do{
                                    try viewContext.save()
                                } catch{
                                    
                                }
                            }
                        } message: {
                            Text("This will remove the Ingredient from all Recipes!")
                        }
                    }
               }
           }
        }
    }

CodePudding user response:

Its because you are using the same boolean for every item. Try making custom View struct for each row, that has its own boolean, e.g.

struct IngredientsList: View {

    @FetchRequest(sortDescriptors: []) private var ingredients: FetchedResults<Ingredient>

    var body: some View {
        List{
            ForEach(ingredients){ ingredient in
                IngredientRow(ingredient: ingredient)
           }
        }
    }
}

struct IngredientRow: View {
    @Environment(\.managedObjectContext) private var viewContext
    @State var confirm = false
    @ObservedObject var ingredient: Ingredient

    var body: some View {
        NavigationLink{
            IngredientDetail(ingredient: ingredient)
        } label: {
            Text(ingredients.ingredientname ?? "")
        }
        .swipeActions {
            Button(role: .destructive){
                confirm = true
            } label: {
                Text("Delete")
            }
         }
         .contextMenu {
               Button(role: .destructive){
                    confirm = true
               } label:{
                    Text("Delete")
               }
         }
         .confirmationDialog("Are you sure?", isPresented: $confirm){
              Button("Delete Ingredient"){
                  viewContext.delete(ingredient)
                  do {
                      try viewContext.save()
                  } catch {
                  }
             }
        } message: {
               Text("This will remove the Ingredient from all Recipes!")
        }
    }
}

And btw, without a valid sortDescriptor the list might not behave correctly.

  • Related