SwiftUI 和 CoreData:将 FetchResults 传递给 DetailView 并更新它们
SwiftUI and CoreData : passing FetchResults to a DetailView and updating them
代码更新以反映下面的答案。仍然愿意跳过 $newName
并执行类似 TextField("New name...", text: $pcard.name)
的操作,但这会引发错误。
长期搜索者第一次提问者。 Whosebug 非常宝贵。
寻找有关在详细信息视图中更新核心数据实体的单个“行”的最佳做法的一些指导。显然我做错了,因为我无法让它工作,而且似乎没有很多关于这个看似简单的特定用例的讨论。
我的应用程序有一个标准的 MasterList/Detail 结构,我想将在详细信息视图中所做的更新绑定到在列表视图中获取的实体。
下面的代码,这是我感兴趣的 passing/binding/updating 部分。感谢任何帮助,无论是概念上的(这里是它的设计工作方式)还是实践上的(这样做)。
谢谢。
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)
}
}
无需创建@State newName。 @ObservedObject 已经做了你要找的东西。请阅读这篇文章:
https://purple.telstra.com/blog/swiftui---state-vs--stateobject-vs--observedobject-vs--environme
代码更新以反映下面的答案。仍然愿意跳过 $newName
并执行类似 TextField("New name...", text: $pcard.name)
的操作,但这会引发错误。
长期搜索者第一次提问者。 Whosebug 非常宝贵。
寻找有关在详细信息视图中更新核心数据实体的单个“行”的最佳做法的一些指导。显然我做错了,因为我无法让它工作,而且似乎没有很多关于这个看似简单的特定用例的讨论。
我的应用程序有一个标准的 MasterList/Detail 结构,我想将在详细信息视图中所做的更新绑定到在列表视图中获取的实体。
下面的代码,这是我感兴趣的 passing/binding/updating 部分。感谢任何帮助,无论是概念上的(这里是它的设计工作方式)还是实践上的(这样做)。
谢谢。
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)
}
}
无需创建@State newName。 @ObservedObject 已经做了你要找的东西。请阅读这篇文章: https://purple.telstra.com/blog/swiftui---state-vs--stateobject-vs--observedobject-vs--environme