SwiftUI:重置 TabView

问题描述

我在 TabView 生命周期应用中有一个带有两个选项卡的 SwiftUI,其中一个具有复杂的视图结构:NavigationView 里面有很多子视图,即:{{ 1}} 和它们的 NavigationLink 分布在视图树的多个级别,每个子视图本身就是另一个具有 DestinationView 和/或其他 sheet 的视图层次结构.在此层次结构中的某个点,我想将 DestinationView 重置为其显示一个视图的原始状态,以便用户可以在该状态下重新开始他们的旅程,因为他们要为第一次,所以有点不可能追踪 TabViewisActive 绑定之类的东西来弹出或关闭视图和工作表。

我想将 isPresented 包装在另一个视图中:TabView 试图找到一种简单的方法从头开始重新创建 RootView 或类似刷新 / 重置 TabView,但找不到有关如何操作的提示

这是我的代码片段:

TabView

附言我不是在寻找“从视图弹出到根视图”,因为当有许多活动的 @main struct TestApp: App { var body: some Scene { WindowGroup { RootView() } } } struct RootView: View { var body: some View { ContentView() } } struct ContentView: View { var body: some View { TabView { // <-- I need to reset it to its original state View1() // <---- this view has complex view hierarchy .tabItem { Text("Home") }.tag(0) View2() .tabItem { Text("Settings") }.tag(1) } } } 目的地用户可能会打开其中一张工作表时,这无法完成并在工作表内开始新的导航之旅。

****** 更新 ******

我创建了一个新的 NavigationLink 值来保存一个布尔值,该值应该指示 Environment 是否应该重置,并且我已经跟踪了每个 TabView 和 {{1} } 每个视图中的状态变量,并在环境值设置为 isPresented 后重置它们,如下所示:

isActive

在将显示工作表或推送新视图的每个视图中,我添加了如下内容

true

并在最后一个视图中(将重置 struct ResetTabView: EnvironmentKey { static var defaultValue: Binding<ResetTabObservable> = .constant(ResetTabObservable()) } extension EnvironmentValues { var resetTabView: Binding<ResetTabObservable> { get { self[ResetTabView.self] } set { self[ResetTabView.self] = newValue } } } class ResetTabObservable: ObservableObject { @Published var newValue = false } )我像这样切换 struct View3: View { @State var showSheet = false @Environment(\.resetTabView) var reset var body: some View { Text("This is view 3") Button(action: { showSheet = true },label: { Text("show view 4") }) .sheet(isPresented: $showSheet) { View4() } .onReceive(reset.$newValue.wrappedValue,perform: { val in if val == true { showSheet = false } }) } } 值:

TabView

这导致了对视图的尴尬拒绝:

enter image description here

解决方法

我为此所做的是使用@SceneStorage("key")(而不是@State)存储我所有的演示文稿绑定,这样它们不仅尊重状态恢复!但是您也可以使用相同的密钥在整个应用程序中轻松访问它们。 This post 提供了一个很好的示例,说明如何在 iPad 上实现从 Tab 视图切换到侧边栏视图。

我在我的应用程序中使用了它,所以如果我有一个按钮或需要展开许多演示的东西,它可以读取所有这些值并将它们重置回所需的值,而无需传递大量绑定。

>