首页 > 解决方案 > SwiftUI 和 CoreData:将 FetchResults 传递给 DetailView 并更新它们

问题描述

代码更新以反映下面的答案。仍然愿意跳过$newName并做类似的事情,TextField("New name...", text: $pcard.name)但这会引发错误。


长期搜索者第一次提问者。StackOverflow 非常宝贵。

寻找一些关于在详细视图中更新核心数据实体的单个“行”的最佳实践指南。显然我正在处理这个错误,因为我无法让它工作,而且似乎没有很多关于这个看似简单的特定用例的讨论。

我的应用程序有一个标准的 MasterList/Detail 结构,我想将在详细视图中进行的更新绑定到在列表视图中获取的实体。

下面的代码,这是我感兴趣的传递/绑定/更新部分。任何帮助表示赞赏,无论是概念上的(这是它的设计工作方式)还是实际的(这样做)。

谢谢。

import SwiftUI

struct ListView: View {
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(
        entity: PCard.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \PCard.name, ascending: true)],
        animation: .default
    ) private var pcards: FetchedResults<PCard>
    
    var body: some View {
        NavigationView {
            List {
                ForEach(pcards) { pcard in
                    NavigationLink(destination: DetailView(pcard: pcard)) {
                        Text(pcard.name ?? "no name specified")
                    }
                }
            }
            .navigationTitle("My Cards")
        }
    }
}

struct DetailView: View {
    @Environment(\.managedObjectContext) private var viewContext
    @State private var newName: String = ""
    
    @ObservedObject var pcard: PCard
    
    var body: some View {
        
        VStack {
            Text(pcard.name ?? "no name specified").font(.largeTitle)
            TextField("New name...", text: $newName).textFieldStyle(RoundedBorderTextFieldStyle())
            Button(action: {
                pcard.name = newName
                do {
                    try viewContext.save()
                } catch {
                    let nsError = error as NSError
                    fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
                }
                
            }) {
                //label
                Label("Update", systemImage: "sparkles")
            }
            Spacer()
        }
        .padding()
        
    }
}

struct ListView_Previews: PreviewProvider {
    static var previews: some View {
        ListView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}

标签: swiftcore-dataswiftui

解决方案


无需创建@State newName。@ObservedObject 已经做了你想要的。请阅读这篇文章: https ://purple.telstra.com/blog/swiftui---state-vs--stateobject-vs--observedobject-vs--environme


推荐阅读