У меня есть 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.
- Создайте новый файл Swift с именем Task. Скопируйте код для задачи и вставьте в Task.swift.
- Добавьте объекты в ProjectName.xcdatamodeld в соответствии с изображением ниже.
- Запустить
Я использую Xcode 11.4.
Дайте мне знать, если вам понадобится дополнительная информация. Любая помощь высоко ценится! Спасибо!