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

Posted

技术标签:

【中文标题】SwiftUI - 核心数据从按钮中删除项目【英文标题】:SwiftUI - Core Data delete item from button 【发布时间】:2021-09-21 06:33:45 【问题描述】:

更新: 我能够让这个工作,不是 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($0.number) == value.element ) 
                                Text(Image(systemName: "heart.fill"))
                                    .foregroundColor(Color.blue)
                            
                        
                        .swipeActions 
                            Button(items.contains(where: Int($0.number) == value.element) ? "Unfavorite" : "Favorite") 
                                if items.contains(where: Int($0.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($0.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 中的项目,按钮操作将项目添加到我的收藏夹View 中的另一个List 使用Core Data。它工作正常,但我不确定如何从我的 Numbers View 中取消收藏和删除核心数据项,这将是我的主要视图。

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

【问题讨论】:

您要删除不喜欢的人还是他们? 这能回答你的问题吗? How to delete Core Data SwiftUI? 不幸的是它没有。我想知道该项目是否已被收藏,以便我可以在主列表中取消收藏。我已经可以删除保存收藏项目的项目 【参考方案1】:

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

1.使用谓词来限制获取请求的结果:

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

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

2.使用过滤器过滤FetchedResults:

items.filter( $0.favorite ) // I could have put == true, but favorite is already a bool, so it evaluates with the ==

这是更常见的方法,因为用户可以访问整个列表,但只需按一下按钮即可将其缩小为收藏夹。简单的方法是使用另一个 bool 在过滤和未过滤的数据之间切换。

【讨论】:

我已经这样做了。那不是我要找的。我有一个号码列表,我想收藏一个号码。然后它将值存储到核心数据中。该数据被放入不同视图的辅助列表中。我还想知道我收藏了数字列表中的哪些项目。 但是您正在存储这样一个事实,即特定托管对象存储的数字还包含它最喜欢的信息是您的解决方案。如果您在视图中使用@FetchRequest,只要您删除托管对象并保存上下文,视图就会刷新以反映更改。因此,如果操作正确,在一个视图中删除托管对象将在所有视图中删除它。这将导致视图更新。 “我还想知道我收藏了号码列表中的哪些项目。”:如果您删除了该项目,它也不再被收藏。 我成功地完成了我一直在寻找的东西,而且没有太多工作要做。 随时为其他人发布您的答案。【参考方案2】:

我能够通过枚举核心数据项来实现这一点,并且能够从我的主要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])
    


【讨论】:

以上是关于SwiftUI - 核心数据从按钮中删除项目的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI .swipeactions 和核心数据

从核心数据中删除/添加到核心数据后,带有列表的 SwiftUI TabView 不刷新

如何从 SwiftUI 列表和领域中删除数据

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

在 macOS 上的 SwiftUI 列表视图中选择和删除核心数据实体

SwiftUI 核心数据