SwiftUI:删除模型后如何弹出详细视图

时间:2020-02-04 23:56:38

标签: swiftui

考虑一个相当简单的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按钮操作之前,该按钮只是在演示问题。实际上,可以在服务器上删除模型,因此不能通过从服务器启动的操作删除该模型。详细信息视图。)

1 个答案:

答案 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()
        }
    }
  }