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
添加到包含Button
的List
中的项目,按钮操作将项目添加到我的收藏夹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 TabView 不刷新
如何在 forEach 循环中删除一个项目,每个项目都有一个 delete btn。我将 swiftUI 与核心数据一起使用