@State var documents: [ScanDocument] = []
func loadDocuments() {
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "ScanDocument")
do {
documents = try managedContext.fetch(fetchRequest) as! [ScanDocument]
print(documents.compactMap({$0.name}))
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
在第一个视图中:
.onAppear(){
self.loadDocuments()
}
现在,我要详细说明一个对象:
NavigationLink(destination: RenameDocumentView(document: documents[selectedDocumentIndex!]), isActive: $pushActive) {
Text("")
}.hidden()
在RenameDocumentView中:
var document: ScanDocument
还有一个用于更新文档名称的功能:
func renameDocument() {
guard !fileName.isEmpty else {return}
document.name = fileName
try? self.moc.save()
print(fileName)
self.presentationMode.wrappedValue.dismiss()
}
所有这些代码均有效。此打印语句始终打印更新的值:
print(documents.compactMap({$0.name}))
这是主视图中的列表代码:
List(documents, id: \.id) { item in
ZStack {
DocumentCell(document: item)
}
}
但是用户返回上一个屏幕。该列表显示了旧数据。如果我重新启动应用程序,它将显示新数据。
任何向新方向移动的帮助都会有所帮助。
这里有一个类似的问题:SwiftUI List View not updating after Core Data entity updated in another View,但没有答案。
答案 0 :(得分:1)
NSManagedObject
是一种引用类型,因此,当您更改其属性时,documents
不会更改,因此状态不会刷新视图。
这是一种在您回来时强制刷新列表的方法
@State var documents: [ScanDocument] = []
@State private var refreshID = UUID() // can be actually anything, but unique
List(documents, id: \.id) { item in
ZStack {
DocumentCell(document: item)
}
}.id(refreshID) // << here
NavigationLink(destination: RenameDocumentView(document: documents[selectedDocumentIndex!])
.onDisappear(perform: {self.refreshID = UUID()}),
isActive: $pushActive) {
Text("")
}.hidden()
替代:可能的替代方法是使DocumentCell
观察文档,但是未提供代码,因此不清楚其中的内容。无论如何,您都可以尝试
struct DocumentCell: View {
@ObservedObject document: ScanDocument
...
}
答案 1 :(得分:0)
Core Data 批量更新不会更新内存中的对象。之后您必须手动刷新。
批量操作绕过普通的 Core Data 操作,直接在底层 SQLite 数据库(或任何支持持久存储的数据库)上操作。他们这样做是为了提高速度,但这意味着他们也不会触发您使用正常获取请求获得的所有内容。
您需要执行 Apple 的 Core Data Batch Programming Guide:Implementing Batch Updates - Updating Your Application After Execution 中所示的操作
Original answer similar case similar case
let request = NSBatchUpdateRequest(entity: ScanDocument.entity())
request.resultType = .updatedObjectIDsResultType
let result = try viewContext.execute(request) as? NSBatchUpdateResult
let objectIDArray = result?.result as? [NSManagedObjectID]
let changes = [NSUpdatedObjectsKey: objectIDArray]
NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [managedContext])