如何在 forEach 循环中删除一个项目,每个项目都有一个 delete btn。我将 swiftUI 与核心数据一起使用

Posted

技术标签:

【中文标题】如何在 forEach 循环中删除一个项目,每个项目都有一个 delete btn。我将 swiftUI 与核心数据一起使用【英文标题】:how to delete an item in a forEach loop with a delete btn for each of it. I use swiftUI with core data 【发布时间】:2021-11-14 09:37:14 【问题描述】:

如果你不明白,这里是代码

struct cartView: View 
        @Environment(\.managedObjectContext) private var viewContext
    
        @FetchRequest(
            sortDescriptors: [], animation: .default) private var products: FetchedResults<Prod>
        
        let columns = [GridItem(.flexible()), GridItem(.flexible())]
        @State var indx = 0
    
        var body: some View 
            NavigationView 
                ScrollView 
                    VStack 
                        LazyVGrid(columns: columns) 
                            ForEach(products, id: \.self) prod in
                                let prodItems = Product(name: prod.name ?? "Undefined", price: prod.price ?? "Undefined", type: "type", brand: prod.brand ?? "Undefined", images: [prod.image!,""])
                                
                                    ZStack 
                                    Cells(product: prodItems)
                                    // I want the button below delete the item of the 
                                    // button pressed with the function below
                                    Button(action: ) 
                                        Image(systemName: "xmark.bin.circle")
                                            .resizable()
                                            .frame(width: 30, height: 30)
                                            .foregroundColor(.red)
                                            .background(.black)
                                            .clipShape(RoundedRectangle(cornerRadius: 20))
                                            .offset(x: 60, y: 45)
                                    
                                
                            
                        
                    
                
                .navigationTitle("Cart")
            
        
        
        private func deleteItems(offsets: IndexSet) 
            withAnimation 
                offsets.map  products[$0] .forEach(viewContext.delete)
    
                do 
                    try viewContext.save()
                 catch 
                    let nsError = error as NSError
                    fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
                
            
        


所以这里的问题是 forEach 循环中的按钮,用于删除用户按下按钮的项目,我知道该怎么做,但我不知道如何获取项目的索引和在函数中传递它。

【问题讨论】:

这是你的答案吗? ***.com/a/68509759/14733292这个也有帮助:***.com/a/68587880/14733292 这能回答你的问题吗? How to delete Core Data SwiftUI? 【参考方案1】:

如果您从循环中发出删除指令,您实际上并不需要索引,因为您的 NSManagedObjectContext 实例有一个采用对象本身的 delete(_:) 方法。该更改将自动通过您的 @FetchRequest 对象传播,您的 SwiftUI 视图将更新以显示没有现在删除的对象的集合。

所以你的按钮动作变成:

Button(action: 
  viewContext.delete(prod)
) 
  Image(systemName: ...)
  // etc.

请注意,虽然您会立即看到效果,但删除只会在内存中,直到您在托管对象上下文上调用 save

在我的 CoreData 应用程序中,我倾向于单独保存我的更改,例如当应用程序即将进入后台时。但是如果你想在对象被移除后立即触发保存,这很简单:

Button(action: 
  viewContext.delete(prod)
  try? viewContext.save()
) 
  Image(systemName: ...)
  // etc.

注意:NSManagedObjectContext.save() 的文档说您应该在尝试保存之前检查hasChanges 属性,但是由于您刚刚在上面的行中进行了更改,因此在此特定示例中没有必要这样做.

【讨论】:

非常感谢,它有效,你真的帮助了我!

以上是关于如何在 forEach 循环中删除一个项目,每个项目都有一个 delete btn。我将 swiftUI 与核心数据一起使用的主要内容,如果未能解决你的问题,请参考以下文章

在 foreach 循环中删除重复项(但计算它们) - Laravel 8

删除每个循环中的所有项目?

如何在每个循环中转到下一个

在 ForEach 循环中删除项目会导致致命错误:索引超出范围

如何在 foreach 循环中删除数组元素?

如何使用 php 函数在数组中查找项目及其后的项目