从字典中删除项目,然后将其保存到SwiftUi中的NSManageBject

发布于 2025-02-07 14:33:33 字数 3021 浏览 1 评论 0原文

我是Swift的新手,我正在使用Core Data和Swiftui进行帐户的申请。问题是,当我尝试从列表中删除项目时,它不会以正确的索引。可能是因为我应用了一种通过词典中按日期从fetchrequest分组的方法,并通过各节将其显示在UI中。

因此,当我重写DELETE函数以使其现在采用新索引时,我会收到一个错误,说:“不能将类型'[expenselog]'的值转换为预期参数类型'nsmanagedObject'”,因为我以前已经制作过词典的更改。

有没有办法通过将小组保留部分来删除核心数据项? 因为如果我删除创建各节的foreach,则索引再次正确,我可以从核心数据中删除正确的项目。但这不是我想要的。

import SwiftUI
import CoreData

struct LogListView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(sortDescriptors: [SortDescriptor(\ExpenseLog.date, order: .reverse)]) var logs: FetchedResults<ExpenseLog>
    
    @State var logToEdit: ExpenseLog?
    @State var searchText = ""
    
    var dateFormatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateStyle = .long
        return formatter
    }
    
    var sections: [[ExpenseLog]] {
        ExpenseLog.update(Array(logs), and: dateFormatter)
    }
    
    var body: some View {
        List {
            ForEach(sections, id: \.self) { (section: [ExpenseLog]) in
                Section(header: Text(dateFormatter.string(from: section[0].date!))) {
                    ForEach(section.filter({
                        self.searchText.isEmpty ? true :
                        $0.name!.localizedStandardContains(self.searchText)
                    }), id: \.id) { log in
                        Button {
                            logToEdit = log
                        } label: {
                            HStack(spacing: 16) {
                                CategoryIconsView(category: log.categoryEnum)
                                VStack(alignment: .leading, spacing: 8) {
                                    Text(log.nameText).font(.subheadline)
                                    Text(log.dataText)
                                }
                                Spacer()
                                Text(log.typeTransaction != "expensive" ? log.amountText : "-\(log.amountText)").font(.subheadline).foregroundColor(log.typeTransaction == "income" ? .green : .primary)
                            }
                            .padding(.vertical, 4)
                        }
                    }
                }
            }
            .onDelete(perform: deleteItem)
        }
    }
    
     func deleteItem(at offsets: IndexSet) {
         var sec = sections
         sec.remove(atOffsets: offsets)
         
         offsets.forEach { index in
             let log = sec[index]
             moc.delete(log) // Error: Cannot convert value of type '[ExpenseLog]' to expected argument type 'NSManagedObject'
         
        try? moc.saveContext()
    }

这是通过费用扩展中的日期对获得的方法进行分组的方法。

static func update(_ result: [ExpenseLog], and dateFormatter: DateFormatter) -> [[ExpenseLog]] {
        return Dictionary(grouping: result) { (element : ExpenseLog)  in
            dateFormatter.string(from: element.date!)
        }.values.sorted() { $0[0].date! > $1[0].date! }
    }

非常感谢您。

I'm new to Swift and I'm making an application to account expenses using Core Data and SwiftUI. The problem is that when I try to delete items from the List, it does not do so in the correct index. Probably because I applied a method that groups the items from the FetchRequest by date in a dictionary and displays them in the UI by Sections.

So, when I have rewritten the delete function so that it now takes the new indexes, I get an error that says: "Cannot convert value of type '[ExpenseLog]' to expected argument type 'NSManagedObject'", because I have previously made the change to the Dictionary.

Is there a way to be able to delete Core Data items by keeping the group by sections?
Because If I delete the ForEach that creates the Sections, the index is correct again and I can remove the correct item from Core Data. But that's not really what I want.

import SwiftUI
import CoreData

struct LogListView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(sortDescriptors: [SortDescriptor(\ExpenseLog.date, order: .reverse)]) var logs: FetchedResults<ExpenseLog>
    
    @State var logToEdit: ExpenseLog?
    @State var searchText = ""
    
    var dateFormatter: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateStyle = .long
        return formatter
    }
    
    var sections: [[ExpenseLog]] {
        ExpenseLog.update(Array(logs), and: dateFormatter)
    }
    
    var body: some View {
        List {
            ForEach(sections, id: \.self) { (section: [ExpenseLog]) in
                Section(header: Text(dateFormatter.string(from: section[0].date!))) {
                    ForEach(section.filter({
                        self.searchText.isEmpty ? true :
                        $0.name!.localizedStandardContains(self.searchText)
                    }), id: \.id) { log in
                        Button {
                            logToEdit = log
                        } label: {
                            HStack(spacing: 16) {
                                CategoryIconsView(category: log.categoryEnum)
                                VStack(alignment: .leading, spacing: 8) {
                                    Text(log.nameText).font(.subheadline)
                                    Text(log.dataText)
                                }
                                Spacer()
                                Text(log.typeTransaction != "expensive" ? log.amountText : "-\(log.amountText)").font(.subheadline).foregroundColor(log.typeTransaction == "income" ? .green : .primary)
                            }
                            .padding(.vertical, 4)
                        }
                    }
                }
            }
            .onDelete(perform: deleteItem)
        }
    }
    
     func deleteItem(at offsets: IndexSet) {
         var sec = sections
         sec.remove(atOffsets: offsets)
         
         offsets.forEach { index in
             let log = sec[index]
             moc.delete(log) // Error: Cannot convert value of type '[ExpenseLog]' to expected argument type 'NSManagedObject'
         
        try? moc.saveContext()
    }

And here is the method that groups the FetchedResults by dates in the ExpensesLog extension.

static func update(_ result: [ExpenseLog], and dateFormatter: DateFormatter) -> [[ExpenseLog]] {
        return Dictionary(grouping: result) { (element : ExpenseLog)  in
            dateFormatter.string(from: element.date!)
        }.values.sorted() { $0[0].date! > $1[0].date! }
    }

Thank you very much in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文