我有一个NavigationView,其中包含一个列表,显示来自CoreData FetchRequest的任务。FetchRequest按Task.dueDate升序排序。TaskDetail视图基本上由标题的TextField和日期选择器组成。更改详细视图中的值有效。但是,每次尝试更改日期值时,我都会得到一些奇怪的行为。日期会更改,但导航视图会自动退出详细视图并返回到列表视图。仅当我以某种方式更改日期以使列表由于排序而重新排列时才会发生这种情况。
如何防止上述奇怪的行为?
创建一个可运行的最小化可复现版本,需要执行以下步骤:
如何防止上述奇怪的行为?
//
// ContentView.swift
import SwiftUI
import CoreData
struct ContentView: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(fetchRequest: Task.requestAllTasks()) var tasks: FetchedResults<Task>
var body: some View {
NavigationView {
List(tasks, id: \.id) { task in
NavigationLink(destination: TaskDetail(task: task)) {
Text("\(task.title)")
}
}.navigationBarTitle("Tasks").navigationBarItems(trailing: Button("new") {self.addTask()})
}
}
func addTask() -> Void {
let newTask = Task(context: self.moc)
newTask.id = UUID()
newTask.title = "task \(tasks.count)"
newTask.dueDate = Date()
print("created new Task")
if (self.moc.hasChanges) {
try? self.moc.save()
print("saved MOC")
}
print(self.tasks)
}
}
struct TaskDetail : View {
@ObservedObject var task: Task
var body: some View {
VStack{
TextField("name", text: $task.title)
DatePicker("dueDate", selection: $task.dueDate, displayedComponents: .date)
.labelsHidden()
}
}
}
//
// Task.swift
import Foundation
import CoreData
public class Task: NSManagedObject, Identifiable {
@NSManaged public var id: UUID?
@NSManaged public var dueDate: Date
@NSManaged public var title: String
static func requestAllTasks() -> NSFetchRequest<Task> {
let request: NSFetchRequest<Task> = Task.fetchRequest() as! NSFetchRequest<Task>
let sortDescriptor = NSSortDescriptor(key: "dueDate", ascending: true)
request.sortDescriptors = [sortDescriptor]
return request
}
}
创建一个可运行的最小化可复现版本,需要执行以下步骤:
- 创建一个新的Xcode“Single View App”项目。确保勾选了CoreData复选框。
- 将上面的ContentView代码复制并粘贴/替换到ContentView.swift中。
- 创建一个名为Task的新Swift文件。复制Task的代码并粘贴到Task.swift中。
- 根据下图在ProjectName.xcdatamodeld中添加实体。
- 运行
我使用的是 Xcode 11.4 版本。
如果您需要更多信息,请告诉我。 非常感谢您的帮助!谢谢!
NavigationLink().id(task)
。如果不起作用,则更改设计,例如编辑应用于结束编辑时将数据对象应用于数据库的临时数据对象。 - Asperi