首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI:重置TabView

SwiftUI:重置TabView
EN

Stack Overflow用户
提问于 2021-04-11 13:44:21
回答 1查看 765关注 0票数 4

我有一个TabView,在SwiftUI生命周期应用程序中有两个选项卡,其中一个具有复杂的视图结构:包含大量子视图的NavigationView,即:NavigationLink和它们的DestinationView被分散在视图树的多个层次上,每个子视图本身就是另一个具有sheets和/或其他DestinationView的视图层次结构。在这个层次结构中的某个时候,我希望将TabView重新设置为显示第一个视图的原始状态,这样用户就可以在这个状态下重新启动他们的旅程,由于他们是第一次打开这个应用程序,所以不可能找到类似isActive & isPresented的绑定来弹出或忽略视图和页面。

我想把TabView封装到另一个视图中:RootView试图找到一种简单的方法从头创建这个TabView,或者像刷新/重置TabView之类的东西,但却找不到如何做的线索。

下面是我的代码片段:

代码语言:javascript
复制
@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是否应该重置,并且我跟踪了每个视图中的每个isPresentedisActive状态变量,并在环境值设置为true后重新设置它们,如下所示:

代码语言:javascript
复制
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
}

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

代码语言:javascript
复制
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值如下:

代码语言:javascript
复制
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")
            })
        }
    }
}

这导致了因以下观点而被驳回的尴尬:

EN

回答 1

Stack Overflow用户

发布于 2021-04-12 05:42:30

我所做的就是让我所有的表示绑定都使用@SceneStorage("key") (而不是@ state )来存储,这样他们不仅尊重状态恢复!但是通过使用相同的键,你也可以轻松地在整个应用程序中访问它们。这个职位给出了一个很好的示例,说明如何在iPad上实现从Tab到Sidebar视图的切换。

我在我的应用程序中使用了这一点,所以如果我有一个按钮或什么东西需要解压许多演示文稿,它可以读取所有这些值,并将它们重新设置为想要的值,而无需传递大量的绑定。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67045695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档