在其他视图中更新核心数据属性时,SwiftUI 列表不会更新 [英] SwiftUI List not updating when core data property is updated in other view

查看:29
本文介绍了在其他视图中更新核心数据属性时,SwiftUI 列表不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@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()
 }

现在我正在推动一个对象的详细视图:

Now I'm pushing to detail view one single object:

NavigationLink(destination: RenameDocumentView(document: documents[selectedDocumentIndex!]), isActive: $pushActive) {
                    Text("")
                }.hidden()

在重命名文档视图中:

var document: ScanDocument

还有一个函数来更新文档名称:

Also, one function to update the document name:

func renameDocument() {
    guard !fileName.isEmpty else {return}
    document.name = fileName
    try? self.moc.save()
    print(fileName)
    self.presentationMode.wrappedValue.dismiss()
}

所有这些代码都有效.此打印语句始终打印更新的值:

All this code works. This print statement always prints updated value:

print(documents.compactMap({$0.name}))

这是主视图中的列表代码:

Here's the list code in main View:

List(documents, id: \.id) { item in
     ZStack {
          DocumentCell(document: item)
     }
}

但是用户返回到上一个屏幕的地方.该列表显示旧数据.如果我重新启动应用程序,它会显示新数据.

But where user comes back to previous screen. The list shows old data. If I restart the app it shows new data.

任何推动新方向的帮助都会有所帮助.

Any help of nudge in a new direction would help.

这里有一个类似的问题:在另一个视图中更新核心数据实体后,SwiftUI 列表视图未更新,但没有答案.

There is a similar question here: SwiftUI List View not updating after Core Data entity updated in another View, but it's without answers.

推荐答案

NSManagedObject 是一个引用类型,所以当你改变它的属性时你的 documents 不会改变,所以声明不刷新视图.

NSManagedObject is a reference type so when you change its properties your documents is not changed, so state does not refresh view.

这是一种在您回来时强制刷新列表的可能方法

Here is a possible approach to force-refresh List when you comes back

  1. 添加新状态

@State var documents: [ScanDocument] = []
@State private var refreshID = UUID()   // can be actually anything, but unique

  1. 制作由它标识的列表

List(documents, id: \.id) { item in
     ZStack {
          DocumentCell(document: item)
     }
}.id(refreshID)     // << here

  1. 返回时更改refreshID,从而强制重建列表

NavigationLink(destination: RenameDocumentView(document: documents[selectedDocumentIndex!])
                               .onDisappear(perform: {self.refreshID = UUID()}), 
                isActive: $pushActive) {
                    Text("")
                }.hidden()

替代方案: 可能的替代方案是让 DocumentCell 观察文档,但没有提供代码,所以不清楚里面是什么.反正你可以试试

Alternate: Possible alternate is to make DocumentCell observe document, but code is not provided so it is not clear what's inside. Anyway you can try

struct DocumentCell: View {
   @ObservedObject document: ScanDocument
 
   ...
}

这篇关于在其他视图中更新核心数据属性时,SwiftUI 列表不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆