【发布时间】:2019-12-28 02:04:44
【问题描述】:
我正在尝试制作一个可以将值作为@Binding 的编辑表单,对其进行编辑并提交更改。在这种情况下,我使用 @FetchRequest 属性包装器填充一个包含核心数据记录的列表。我想点击一行从 List 导航到 Detail 视图,然后在 Detail 视图上导航到 Edit 视图。
我尝试在没有@Binding 的情况下执行此操作,代码将编译,但是当我进行编辑时,它不会反映在之前的屏幕上。似乎我需要使用@Binding,但我想不出一种方法来获取 List 或 ForEach 中的 NSManagedObject 实例,并将其传递给可以将其用作@Binding 的视图。
列表视图
struct TimelineListView: View {
@Environment(\.managedObjectContext) var managedObjectContext
// The Timeline class has an `allTimelinesFetchRequest` function that can be used here
@FetchRequest(fetchRequest: Timeline.allTimelinesFetchRequest()) var timelines: FetchedResults<Timeline>
@State var openAddModalSheet = false
var body: some View {
return NavigationView {
VStack {
List {
Section(header:
Text("Lists")
) {
ForEach(self.timelines) { timeline in
// ✳️ How to I use the timeline in this list as a @Binding?
NavigationLink(destination: TimelineDetailView(timeline: $timeline)) {
TimelineCell(timeline: timeline)
}
}
}
.font(.headline)
}
.listStyle(GroupedListStyle())
}
.navigationBarTitle(Text("Lists"), displayMode: .inline)
}
} // End Body
}
详细视图
struct TimelineDetailView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@Binding var timeline: Timeline
var body: some View {
List {
Section {
NavigationLink(destination: TimelineEditView(timeline: $timeline)) {
TimelineCell(timeline: timeline)
}
}
Section {
Text("Event data here")
Text("Another event here")
Text("A third event here")
}
}.listStyle(GroupedListStyle())
}
}
编辑视图
struct TimelineEditView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@State private var newDataValue = ""
@Binding var timeline: Timeline
var body: some View {
return VStack {
TextField("Data to edit", text: self.$newDataValue)
.shadow(color: .secondary, radius: 1, x: 0, y: 0)
.textFieldStyle(RoundedBorderTextFieldStyle())
.onAppear {
self.newDataValue = self.timeline.name ?? ""
}.padding()
Spacer()
}
.navigationBarItems(
leading:
Button(action: ({
// Dismiss the modal sheet
self.newDataValue = ""
self.presentationMode.wrappedValue.dismiss()
})) {
Text("Cancel")
},
trailing: Button(action: ({
self.timeline.name = self.newDataValue
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
// Dismiss the modal sheet
self.newDataValue = ""
self.presentationMode.wrappedValue.dismiss()
})) {
Text("Done")
}
)
}
}
我应该提到,我什至尝试这样做的唯一原因是因为模态 .sheet() 的东西是超级错误的。
【问题讨论】:
-
您是否要保存任何单个字符的文本更改或用户按下按钮时?
-
我想导航到具有各种数据输入控件(如表单和选择器)的视图。我想要一个取消按钮来放弃更改,以及一个完成按钮来保存更改。如果您查看 iOS13 Reminders 应用程序中的列表创建和编辑功能,那几乎就是我想要的,除了模态 .sheet() 修饰符之外我什么都没有。
-
嗯。我不确定人们通常如何保存来自
FetchedResults的数据,但我想任何条目都可以从任何地方保存。因此,您不需要在特定条目上使用@Binding,因为保存 (moc.save()) 这意味着它会自动更新您的事实来源。这是我最好的猜测。 -
当我在没有@Binding 的情况下执行此操作时,我可以将更改保存到 MOC 并且该部分有效,但之前屏幕上的视图不会更新。我必须退出并重新启动应用才能看到所反映的更改。
-
我在尝试使用 Binding 时遇到了问题,但使用 @ObservedObject 会更好