如何正确更新详细视图中的 CoreData 对象?

Posted

技术标签:

【中文标题】如何正确更新详细视图中的 CoreData 对象?【英文标题】:How do I update a CoreData object in a detail view correctly? 【发布时间】:2020-04-11 22:36:59 【问题描述】:

我想要一个简单的应用程序,它有一个排序的项目列表。单击每个项目进入详细视图,单击另一个按钮会更新项目的字段,该字段应重绘原始列表。

列表视图由以下给出:

import SwiftUI
import CoreData

struct ContentView: View 

    @Environment(\.managedObjectContext) var context 

    @State private var itemName: String = ""

    // get all data, sorted by date
    @FetchRequest(
        entity: Item.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.lastEdited, ascending: true)]
    ) var allItems: FetchedResults<Item>



    var body: some View 

        NavigationView 
            List 
                ForEach (allItems)  item in
                    NavigationLink(destination: DetailView(item: item).environment(\.managedObjectContext, self.context)) 
                        Text(item.name ?? "No name given")
                     // nav link

                


            
    



详细视图由下式给出:


import SwiftUI
import CoreData


struct DetailView: View 


    @Environment(\.managedObjectContext) var context

    var item: FetchedResults<Item>.Element

    var body: some View 

        Button (action: 
            self.updateDate(item: self.item)

            ) 
                Text("Press me!")
            

     // body

    func updateDate(item: Item) 
        item.lastEdited = Date()
     // func

 // DetailView



按下详细视图上的“按我”按钮会导致更新生效,列表视图也会更新,但是当我按下按钮时会发生这种情况:

    显示带有详细视图的新屏幕 返回列表视图

为什么 (1) 会发生?我该如何避免这种情况?

我在我的 xcdatamodeld 中将 Item 定义为实体

【问题讨论】:

ContentView 你有destination: DetailView(item: item).envir... item 定义在哪里?您的意思是改为传递recipe 吗? This topic 应该会有所帮助。 【参考方案1】:

改变

var item: FetchedResults<Item>.Element

@ObservedObject var item: Item

这可能是因为父级正在重绘。

【讨论】:

这实际上很好地解决了这个问题,但我真的不明白为什么。父级重绘不会停止渲染细节视图吗?为什么这有什么不同? 所有 CoreData 对象都是 ObservableObjects。通过正确包装它,您可以让 SwiftUI 只呈现需要的内容。如果解决了,你会接受答案吗?【参考方案2】:

在 DetailView 中进行更改,试试这个。它将保存您所做的更改。

do 
    try self.context.save()
 catch 
    print(error)

【讨论】:

@JoepBeusenberg,在您没有保存数据之前,它不会在任何其他屏幕上更新 还要看问题标题“如何正确更新详细视图中的CoreData对象?”,要正确更新,正确保存是其中的一部分。 当前的问题是导航会随着数据的更新而改变。所以也许是的,保存是正确行事的一部分,它并不能解决问题。 可以,但前提是您将该字段正确标记为@ObservedObject。所以这是一个有价值的补充,但它并没有回答这个问题。

以上是关于如何正确更新详细视图中的 CoreData 对象?的主要内容,如果未能解决你的问题,请参考以下文章

使用 RestKit 和 CoreData 同步修改对象的正确方法

如何使用更新的数据刷新 NSManagedObject - Core Data

当 coreData 值发生变化时,如何更新我的其他视图?

无法在 SwiftUI 中使用 ForEach 和 CoreData 将数据正确传递给模态演示

使用 SwiftUI 在 CoreData 中处理 Header / Detail 视图的正确方法

从集合视图移动到详细视图时如何利用 CoreData