Seb*_*bbe 7 core-data list master-detail swift swiftui
我有一个带有列表的 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
}
}
Run Code Online (Sandbox Code Playgroud)
要创建一个正在运行的最小可重现版本...请执行以下操作:
我在 Xcode 11.4 上。
如果您需要我提供更多信息,请告诉我。任何帮助深表感谢!谢谢!
更新2(iOS 14 beta 3)
该问题似乎在 iOS 14 beta 3 中得到了解决:在进行影响排序顺序的更改时,详细信息视图不再弹出。
更新
苹果似乎将此视为一项功能,而不是一个错误;今天他们对我关于这个问题的反馈(FB7651251)回复如下:
如果这是您想要的行为,我们建议您使用 isActive 并使用选择绑定自行管理推送。这是正确的行为。
这是因为当您更改排序顺序时,推送视图的标识也会发生变化。
正如我在上面的评论中提到的,我相信这是iOS 13.4.
解决方法可能是在列表外部使用 NavigationLink 并将列表行定义为按钮
a)设置要编辑的任务(一个新的@State var selectedTask)和
b) 触发 TaskDetail 的 NavigationLink(task: selectedTask!)。
此设置会将所选任务与其在排序列表中的位置解耦,从而避免因编辑 dueDate 可能导致的重新排序而导致的错误行为。
为了达成这个:
@State private var selectedTask: Task?
@State private var linkIsActive = false
Run Code Online (Sandbox Code Playgroud)
var body: some View {
NavigationView {
ZStack {
NavigationLink(
destination: linkDestination(selectedTask: selectedTask),
isActive: self.$linkIsActive) {
EmptyView()
}
List(tasks) { task in
Button(action: {
self.selectedTask = task
self.linkIsActive = true
}) {
NavigationLink(destination: EmptyView()){
Text("\(task.title)")
}
}
}
}
.navigationBarTitle("Tasks").navigationBarItems(trailing: Button("new") {self.addTask()})
}
}
Run Code Online (Sandbox Code Playgroud)
struct linkDestination: View {
let selectedTask: Task?
var body: some View {
return Group {
if selectedTask != nil {
TaskDetail(task: selectedTask!)
} else {
EmptyView()
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
955 次 |
| 最近记录: |