【发布时间】:2020-02-26 19:09:47
【问题描述】:
在 SwiftUI View 中,我有一个基于 @FetchRequest 的 List 显示 Primary 实体的数据和连接 Secondary 实体的通过关系。
View 及其 List 正确更新,当我添加一个新的 Primary 实体和一个新的相关辅助实体时。
问题是,当我在详细视图中更新连接的Secondary 项目时,数据库会更新,但更改不会反映在Primary 列表中。
显然,@FetchRequest 不会被另一个 View 中的更改触发。
之后,当我在主视图中添加新项目时,之前更改的项目最终会得到更新。
作为一种解决方法,我另外更新了详细视图中Primary 实体的属性,并且更改正确传播到Primary 视图。
我的问题是:
如何强制更新 SwiftUI Core Data 中所有相关的@FetchRequests?
特别是当我无法直接访问相关实体/@Fetchrequests?
import SwiftUI
extension Primary: Identifiable {}
// Primary View
struct PrimaryListView: View {
@Environment(\.managedObjectContext) var context
@FetchRequest(
entity: Primary.entity(),
sortDescriptors: [NSSortDescriptor(key: "primaryName", ascending: true)]
)
var fetchedResults: FetchedResults<Primary>
var body: some View {
List {
ForEach(fetchedResults) { primary in
NavigationLink(destination: SecondaryView(primary: primary)) {
VStack(alignment: .leading) {
Text("\(primary.primaryName ?? "nil")")
Text("\(primary.secondary?.secondaryName ?? "nil")").font(.footnote).foregroundColor(.secondary)
}
}
}
}
.navigationBarTitle("Primary List")
.navigationBarItems(trailing:
Button(action: {self.addNewPrimary()} ) {
Image(systemName: "plus")
}
)
}
private func addNewPrimary() {
let newPrimary = Primary(context: context)
newPrimary.primaryName = "Primary created at \(Date())"
let newSecondary = Secondary(context: context)
newSecondary.secondaryName = "Secondary built at \(Date())"
newPrimary.secondary = newSecondary
try? context.save()
}
}
struct PrimaryListView_Previews: PreviewProvider {
static var previews: some View {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
return NavigationView {
PrimaryListView().environment(\.managedObjectContext, context)
}
}
}
// Detail View
struct SecondaryView: View {
@Environment(\.presentationMode) var presentationMode
var primary: Primary
@State private var newSecondaryName = ""
var body: some View {
VStack {
TextField("Secondary name:", text: $newSecondaryName)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
.onAppear {self.newSecondaryName = self.primary.secondary?.secondaryName ?? "no name"}
Button(action: {self.saveChanges()}) {
Text("Save")
}
.padding()
}
}
private func saveChanges() {
primary.secondary?.secondaryName = newSecondaryName
// TODO: ❌ workaround to trigger update on primary @FetchRequest
primary.managedObjectContext.refresh(primary, mergeChanges: true)
// primary.primaryName = primary.primaryName
try? primary.managedObjectContext?.save()
presentationMode.wrappedValue.dismiss()
}
}
【问题讨论】:
-
没有帮助,抱歉。但我遇到了同样的问题。我的详细视图引用了选定的主要对象。它显示次要对象的列表。所有 CRUD 功能在 Core Data 中都能正常工作,但不会反映在 UI 中。很想了解这方面的更多信息。
-
您是否尝试过使用
ObservableObject? -
我尝试在详细视图中使用 @ObservedObject var primary: Primary。但更改不会传播回主视图。