SwiftUI - 核心数据从按钮中删除项目

SwiftUI - Core Data delete item from button

更新: 我能够让这个工作,而不是 100% 的代码,但它现在正在工作。如果有人有任何改进代码的提示,将不胜感激。我现在可以使用简单的 .swipeAction.

从我的主 List 中删除核心数据项

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.date, ascending: true)], animation: .default)
    private var items: FetchedResults<Item>
    
    var body: some View {
        TabView {
            
            // Main View
            NavigationView {
                List {
                    ForEach(Array((1..<6).enumerated()), id: \.offset) { value in
                        HStack {
                            Text("\(value.element)")
                            Spacer()
                            if items.contains(where: {Int([=10=].number) == value.element} ) {
                                Text(Image(systemName: "heart.fill"))
                                    .foregroundColor(Color.blue)
                            }
                        }
                        .swipeActions {
                            Button(items.contains(where: {Int([=10=].number) == value.element}) ? "Unfavorite" : "Favorite") {
                                if items.contains(where: {Int([=10=].number) == value.element}) {
                                    for (index, element) in items.enumerated() {
                                        if Int(element.number) == value.element {
                                            unfavorite(items[index])
                                        }
                                    }
                                } else {
                                    favorite(Float(value.element))
                                }
                                
                            }
                            .tint(items.contains(where: {Int([=10=].number) == value.element}) ? Color.red : Color.blue)
                        }
                    }
                }
                .navigationBarTitle("Numbers")
            }
            .tabItem {
                Image(systemName: "number")
                Text("Numbers")
            }
            
            
            // Saved View is working fine
            NavigationView {
                List {
                    ForEach(items, id: \.self) { item in
                        HStack {
                            Text(String(format: "%.0f", item.number))
                            Spacer()
                            Text(Image(systemName: "heart.fill"))
                                .foregroundColor(Color.blue)
                        }
                    }
                    .onDelete { indexSet in
                        for index in indexSet {
                            viewContext.delete(items[index])
                        }
                        try? viewContext.save()
                    }
                }
                .navigationBarTitle("Favorites")
            }
            .tabItem {
                Image(systemName: "heart.fill")
                Text("Favorites")
            }
        }
    }
    
    func favorite(_ number: Float) {
        let fetchrequest: NSFetchRequest<Item> = Item.fetchRequest()
        fetchrequest.predicate = NSPredicate(format: "number = %f", Float(number))
        do {
            let items = try viewContext.fetch(fetchrequest)
            if !items.isEmpty {
                return
            } else {
                let item = Item(context: viewContext)
                item.number = number
                item.date = Date()
                try? viewContext.save()
            }
        } catch {
            print("error")
        }
    }
    
    func unfavorite(_ item: Item) {
        viewContext.delete(item)
        try? viewContext.save()
    }
}

我正在将 .swipeAction 添加到包含 ButtonList 中的项目,按钮操作将项目添加到另一个 List在我的收藏夹 View 中使用 Core Data。它工作正常,但我不确定如何从我的 Numbers View 中取消收藏和删除核心数据项目,这将是我的主要观点。

我可以在我的第二个 View 中删除保存的项目,只是对如何从主视图中删除感到困惑。 Button 会改为说删除,如果项目已被收藏,颜色将是红色。

您没有显示所有代码,因此很难回答,但我假设您的“主列表”正在分别跟踪“收藏夹”项目列表,这是真实的你的问题的根源。当您像这样使用 CoreData 来显示收藏的列表时,处理它的两种最佳方法是:

1.Using 一个谓词来限制您的获取请求的结果:

let predicate = NSPredicate(format: "favorite == true")

当您只想显示“最喜欢的”项目列表时,最好使用此选项。这基本上是静态的,因为您不能在所有内容和收藏夹之间来回切换(尽管通过正确的实现它会添加收藏的项目)。

2.Filter FetchedResults 使用过滤器:

items.filter( {[=11=].favorite} ) // I could have put == true, but favorite is already a bool, so it evaluates with the ==

这是更常见的方法,因为用户可以访问整个列表,但可以通过按一下按钮将其缩减为仅收藏。简单的方法就是用另一个bool来切换过滤后和未过滤的数据。

我能够通过枚举核心数据项来实现这一点,并且能够从我的主要 List 中删除该项目。完整代码在更新问题的上方。

@Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.date, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>


// This is the solution I found
for (index, element) in items.enumerated() {
    if Int(element.number) == value.element {
        unfavorite(items[index])
    }
}