考虑一个相当简单的SwiftUI应用:一个显示模型列表的列表视图,其中每一行都是一个到详细视图的NavigationLink。使用SwiftUI,对当前查看模型的任何更改都会自动导致UI更新;详细视图始终显示模型的最新版本。万岁! :)
但是在局部视图中删除模型时又如何呢?那什么也没做,您留在了局部视图中。参见下面的一个非常简单的示例,它确实说明了该问题:
struct Model: Identifiable {
let id: Int
var title: String
}
class Store: ObservableObject {
@Published var models = [Model(id: 0, title: "a")]
}
struct ListView: View {
@EnvironmentObject private var store: Store
var body: some View {
NavigationView {
List(store.models) { model in
NavigationLink(destination: DetailView(model: model)) {
Text(model.title)
}
}
.navigationBarTitle("List")
}
}
}
struct DetailView: View {
@EnvironmentObject private var store: Store
var model: Model
var body: some View {
Text(model.title)
.navigationBarTitle("Detail")
.navigationBarItems(trailing: trailingNavigationBarItems)
}
private var trailingNavigationBarItems: some View {
HStack {
Button("Change title") {
self.store.models[0].title = "AAA"
}
Button("Delete model") {
self.store.models.remove(at: 0)
}
}
}
}
详细视图如何识别其模型已不存在并弹出列表视图?就像我说的那样,当前您只是在局部视图上,查看实际上不再存在的模型。当您手动返回列表时,该列表已更新,模型也消失了。
如果要运行此代码,只需将ListView().environmentObject(Store())
用作SceneDelegate中的rootView。
(在任何人说我可以直接弹出Delete按钮操作之前,该按钮只是在演示问题。实际上,可以在服务器上删除模型,因此不能通过从服务器启动的操作删除该模型。详细信息视图。)
答案 0 :(得分:1)
我会这样解决问题。例如,如果我想知道模型是否没有内容,我将通过编程弹出当前视图来自动返回列表视图。而且有效。
struct DetailView: View {
@EnvironmentObject private var store: Store
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var model: Model
var body: some View {
ZStack {
Text(model.title)
}
.navigationBarTitle("Detail")
.navigationBarItems(trailing: trailingNavigationBarItems)
.onReceive(self.store.$models) { model in
if model.count == 0 {
self.presentationMode.wrappedValue.dismiss()
}
}
}