【问题标题】:Swift 2.0 .contextMenu Multiple Delete From Core DataSwift 2.0 .contextMenu 从核心数据中多次删除
【发布时间】:2021-03-06 17:51:20
【问题描述】:

第一次在这里发帖并且是编码新手...所以我希望我遵循正确的协议。我正在 Xcode 12.2 (SwiftUI 2) 中组合一个视图,该视图输出来自 Core Data 的数据列表,并有一个上下文菜单为用户提供编辑、删除和删除多个选项。上下文菜单可以正常进行编辑和删除,但是,我在如何实现删除多个列表项的功能方面遇到了障碍。我想象用户会用力按下列表项之一,上下文菜单弹出打开,如果他们按下“删除多个”选项,视图会激活类似于编辑模式的东西,该模式会在每个项目的左侧填充小圆圈用户一次可以选择和删除多个项目。我可以看到有关如何执行此操作的其他文章,但是,我找不到有关如何通过 Core Data 实现此操作的指导。我在下面粘贴了我的代码。

如果我遗漏了任何其他可以使我的问题更清楚的信息,请告诉我。

我非常感谢论坛的专业知识和指导。

Struct List : View    {
    
    @StateObject var appData = AppViewModel()
    @Environment(\.managedObjectContext) var context
       
    //Fetch Data...
    @FetchRequest(entity: EntryData.entity(), sortDescriptors: [NSSortDescriptor(key: "date", ascending: false)], animation: .spring()) var results : FetchedResults<EntryData>
    
    var body : some View {
        ZStack(alignment: Alignment(horizontal: .trailing, vertical: .bottom), content: {
            VStack{
                ScrollView(.vertical, showsIndicators: false, content: {
                    LazyVStack(alignment: .leading, spacing: 20){
                        ForEach(results){task in
                            VStack(alignment: .leading, spacing: 5, content: {
                                Text(task.category ?? "")
                                    .font(.title)
                                    .fontWeight(.bold)
                                Text(task.date ?? Date(), style:. date)
                                    .fontWeight(.bold)
                                Text("\(task.number.formattedCurrencyText)")
                                
                            })
                            .padding(.horizontal, 14)
                            .padding(.top, 10)
                            .foregroundColor(Color("ColorTextList"))
                            
                            .contextMenu{
                                Button(action: {appData.editItem(item: task)}, label: {
                                    Text("Edit")
                                })
                                Button(action: {
                                    context.delete(task)
                                    try! context.save()
                                }, label: {
                                    Text("Delete")
                                })
                                Button(action: {}, label: {
                                    Text("Delete Mutiple")
                                })
                            }
                        }
                        
                    }
                })
                
            }
            VStack(){
                VisualEffectView(effect: UIBlurEffect(style: .regular))
                    .frame(width: UIScreen.main.bounds.width, height: 50, alignment: .top)
                    .edgesIgnoringSafeArea(.all)
                    .background(Color.clear)
                Spacer()
            }
        })
        .background(Color.clear)
        .sheet(isPresented: $appData.isNewData, content: {
            AddDataView(appData: appData)
                .environment(\.managedObjectContext, self.context)
        })
        
    }
}

添加应用的 viewModel。如何利用这一点并删除多列表选择中的每个属性?

import SwiftUI
import CoreData

class AppViewModel : ObservableObject, Identifiable{
    
    @Published var cateogry = ""
    @Published var date = Date()
    @Published var number : Double? = nil
    @Published var notes = ""
    @Published var id = UUID()
}

并添加实际的 Core Data 模型截图。

【问题讨论】:

    标签: ios core-data swiftui contextmenu delete-row


    【解决方案1】:

    您可以为您的列表实现选择集。这将包含所有被选中的元素。然后您可以根据集合的计数动态显示删除或删除所有的上下文菜单。这是一个完整的deleteAll实现示例

    struct SelectionDemo : View {
        @State var demoData = ["Dave", "Tom", "Phillip", "Steve"]
        @State var selected = Set<String>()
    
        var body: some View {
    
            HStack {
                List(demoData, id: \.self, selection: $selected){ name in
                    Text(name)
                        .contextMenu {
                            Button(action: {
                                //Delete only one item
                            }){
                                Text("Delete")
                            }
                            if (selected.count > 1) {
                                Button(action: {
                                    //Delete all
                                    deleteAll()
                                })
                                {
                                    Text("Delete all")
                                }
                            }
                        }
                }.frame(width: 500, height: 460)
            }
        }
        
        func deleteAll() {
            for element in selected {
                self.demoData.removeAll(where: {
                    $0 == element
                })
            }
        }
    }
    

    【讨论】:

    • 谢谢!但是,我复制了您的代码,但无法选择多行并弹出删除所有功能。当我长按一个项目时,我得到的只是删除。如何在不进入类似于导航视图的“编辑模式”的情况下选择多个项目?此外,这是否适用于存储在 Core Data 中且有多个文件(即名称、日期、金额等)的项目?我做错了什么?
    • 在这方面搞得更多。我猜我卡在 func deleteAll() 中,即 self.demoData.removeAll 行。我不确定如何将其链接到核心数据库以删除所选项目。在您的示例中,它链接到具有一个字段(即名称)的数组。当我用我的 FetchedResults(即 var 结果)替换 demoData 时,我收到一个错误“'FetchedResults' 类型的值没有成员 'removeAll'”。 EntryData 是我的 CoreData 实体的名称。感谢您的指导和反馈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多