我在生命周期应用程序TabView
中有两个选项卡SwiftUI
,其中一个具有复杂的视图结构:NavigationView
内部有很多子视图,即:NavigationLink
s 和它们DestinationView
的 s 分布在视图树的多个级别上,每个子视图在其上own 是另一个带有sheet
s 和/或 other的视图层次结构DestinationView
。在这个层次结构中的某个点,我想将TabView
其重置为显示第一个最多视图的原始状态,这样用户就可以在该状态下重新开始他们的旅程,就像他们第一次打开应用程序一样,所以它是有点不可能找到类似isActive
&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)
}
}
}
ps 我不是在寻找“从视图弹出到根视图NavigationLink
”,因为当用户可能打开其中一个工作表并在工作表内开始新的导航旅程的许多活动目的地时,这是无法完成的。
******更新******
我创建了一个新Environment
值来保存一个布尔值,该布尔值应该指示是否TabView
应该重置,并且我已经跟踪了每个视图中的每个变量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
)中,我像这样切换Environment
值:
struct View5: View {
@Environment(\.resetTabView) var reset
var body: some View {
VStack {
Text("This is view 5")
Button(action: {
reset.newValue.wrappedValue = true
}, label: {
Text("reset tab view")
})
}
}
}
这导致尴尬地驳回意见: