Core data SwiftUI和FetchRequest:延迟列表的重新排序

Core data SwiftUI和FetchRequest:延迟列表的重新排序,core-data,swiftui,Core Data,Swiftui,我已经写了一个显示学生名单的应用程序。为此,我使用了NavigationLink的列表。学生们按照他们的一个属性questionAskedClass排序,这是一个整数。所有这些信息都存储在CoreData中 @Environment(\.managedObjectContext) var managedObjectContext @FetchRequest(entity: Student.entity(), sortDescriptors: [NSSortDescriptor(keyPa

我已经写了一个显示学生名单的应用程序。为此,我使用了
NavigationLink
列表。学生们按照他们的一个属性
questionAskedClass
排序,这是一个整数。所有这些信息都存储在CoreData中

@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(entity: Student.entity(),
    sortDescriptors: [NSSortDescriptor(keyPath: \Student.questionAskedClass,
                                       ascending: true)])
var students: FetchedResults<Student>

var body: some View {
  NavigationView {
    List {
      ForEach(students) {student in
        NavigationLink(destination: StudentView(student: student)) {
          HStack {
            VStack(alignment: .leading) {
              Text("\(student.firstName)").font(.headline).foregroundColor(Color.black)
              Text("\(student.lastName)").font(.headline).foregroundColor(Color.gray)
            }
          }
        }
      }
    }
  }
}
不幸的是,当我更改该属性时,初始列表的顺序将更改,我将被从
StudentView
中删除。框架似乎感觉到列表需要重新排序。但我只想在我返回列表时重新排序这个列表。当我更改
问题askedclass
的值时,不会立即更改

我可以做些什么来缓解这个问题


感谢您的帮助。

您可以尝试创建一个简单的
NSFetchRequest
,并使用此fetch的结果更新您的学生列表

@State var students: [Student] = []

fun refresh() {
    let fetchRequest = NSFetchRequest<Student>(entityName: "Student")
    students = try? managedObjectContext.fetch(fetchRequest) ?? []
}
或者,您可以将上下文保存在主视图的
页面上,而不是
学生视图中:

struct StudentView: View {
    func askQuestion() {
        self.student.questionAskedClass += 1
    }
}

NavigationView {
    ...
}.onAppear {
    try? self.managedObjectContext.save()
}
如果希望在应用程序终止时数据保持不变,请在AppDelegate中添加此函数(假设您的
persistentContainer
已在其中声明:

func applicationWillTerminate(_ application: UIApplication) {
    try? persistentContainer.viewContext.save()
}

抱歉。我对苹果/Swift非常陌生。我应该在
StudentView
中声明
var workingContext
吗?我应该在
askQuestion
函数中同时保存
workingContext
managedObjectContext
吗?我现在意识到你只想在
视图中做任何事情。我已经更新了答案。通常情况下人们在
视图中遇到了问题,
它不会刷新:。感谢您的帮助。我已将FetchRequest替换为
@FetchRequest(entity:Student.entity(),sortDescriptors:[])
和ForEach(students.sorted{$0.questionAskedClass<$1.questionAskedClass})
(我猜这就是您的意思),但FetchRequest仍在
StudentView
中激发。到目前为止,我得到的最好方法是在
StudentView
中创建一个局部变量,当视图出现时存储来自CoreData的
questionAskedClass
,并在视图消失时将其保存回。但如果在
StudentVi中退出应用程序,则不会将其保存回ew
。我认为使用
@FetchRequest
的全部意义在于,您的
students
变量与核心数据中的内容保持最新。当您更改一些
student
时,它会强制重新绘制学生列表视图。要绕过自动刷新,您可以尝试创建一个简单的获取请求
NSFetchRequest
并触发它出现在
页面上
struct StudentView: View {
    func askQuestion() {
        self.student.questionAskedClass += 1
    }
}

NavigationView {
    ...
}.onAppear {
    try? self.managedObjectContext.save()
}
func applicationWillTerminate(_ application: UIApplication) {
    try? persistentContainer.viewContext.save()
}