如何解决为什么用 viewContext 创建一个新的 CloudKit 项会无限刷新视图?
我正在使用托管在 CloudKit 中的存储数据创建一个应用程序。当我对这些列表项中的任何一个执行正常滑动以删除操作时,deleteAlert()
会显示(应该如此)。但是,只要显示警报,代码就会不断循环并创建无限数量的空白 Category
值,并将它们添加到列表中。同时,警报不允许您正常点击任何按钮,但是如果您在按钮上滑动手指,您会感觉到很多短的触觉反馈脉冲(我怀疑它也在循环创建许多重叠警报)。
import SwiftUI
struct CategoryListView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: Category.entity(),sortDescriptors: [],animation: .default)
private var categories: FetchedResults<Category>
// Passed value
var accountSelection: String
@State private var deletingItem = false
@State private var deleteIndexSet: IndexSet?
@State private var showingAddView = false
var body: some View {
List {
ForEach(categories) { category in
HStack {
Button(action: {
self.showingAddView.toggle()
}) {
Text("\(category.name ?? "")")
}
}
.alert(isPresented: $deletingItem,content: deleteAlert)
}
.onDelete { indexSet in
self.deletingItem = true
self.deleteIndexSet = indexSet
}
}
}
func deleteAlert() -> Alert {
var deletedCategory = Category(context: viewContext) // removing this line causes everything to work properly
try! deletedCategory = categories[deleteIndexSet?.first ?? 0]
return Alert(
title: Text("Delete \(deletedCategory.name ?? "nil")?"),message: Text("Deleting \(deletedCategory.name ?? "nil") will not remove all entries from that category."),// TODO: make it so that if entry does not have a category,add it to a "miscellaneous" or "other" category
primaryButton: .cancel(),secondaryButton: .destructive(Text("Delete"),action: {print("")})
)
}
}
解决方法
视图不断刷新的原因归结为 @FetchRequest
的工作方式(CloudKit 获取的项目数组)。每当 categories
的值发生变化时(如 @State
和 @ObservedObject
等),它所附加的视图都会刷新。在这种情况下,以下循环将无休止地重复:
-
在
deleteAlert()
内部,var deletedCategory = Category(context: viewContext)
创建一个新的Category
并立即将其添加到当前上下文(列表)中。 -
这会导致视图刷新,如前所述。
-
$deletingItem
的值仍然为真,因此将显示另一个警报。 -
当显示警报时,它会触发
deleteAlert()
内的代码。 -
冲洗并无限重复步骤 1-4。
TL;DR 不要在 ManagedObjects
/ObservableObjects
中创建 View
/Body
(正如@lorem ipsum 也指出的那样)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。