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
添加到包含 Button
的 List
中的项目,按钮操作将项目添加到另一个 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])
}
}
更新:
我能够让这个工作,而不是 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
添加到包含 Button
的 List
中的项目,按钮操作将项目添加到另一个 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])
}
}