NavigationView inside TabView: How to get to top-level TabView when using the TabItem-Buttons
Asked Answered
B

1

2

I have got my ContentView, which is a TabView, with View1 and View2 as tabs:

struct ContentView: View {
    @State private var selection: Tab = .View1

    enum Tab {
        case View1
        case View2
    }

    var body: some View {
        TabView(selection: $selection) {
            View1()
                .tabItem {
                    Label("View1", systemImage: "")
                }
                .tag(Tab.View1)
                        
            View2()
                .tabItem {
                    Label("View2", systemImage: "")
                }
                .tag(Tab.View2)
        }
    }
}

View1 is a NavigationView with a NavigationLink to a Subview:

struct View1: View {
    var body: some View {
        NavigationView {
            NavigationLink(destination: Text("Subview1")) {
                Text("Hello, View1!")
            }
        }
    }
}

When I'm in the SubView in View1, change via the tabs to View2 and change back (again, via tab) to View1, it restores the Subview, which is fine. How can I achieve that by pressing the tab for View1 again, it gets me to the top-level of View1 (i. e. View1 with "Hello, View1"). As of now I have to use the NavigationLink in the top left corner.

Bridgeport answered 1/2, 2021 at 16:44 Comment(0)
E
3

The possible approach is to use proxy binding with side effect to reset view having navigation view, so git it to initial state.

Demo prepared with Xcode 12.4 / iOS 14.4

demo

struct ContentView: View {
    @State private var selection: Tab = .View1

    // force-reset property
    @State private var reset = UUID()       
    
    enum Tab {
        case View1
        case View2
    }

    var body: some View {

        let proxy = Binding(get: {selection}, set: {
            if selection == $0 {
                reset = UUID()     // << update if same tab clicked !!
            }
            selection = $0
        })

        TabView(selection: proxy) {
            View1()
                .tabItem {
                    Label("View1", systemImage: "")
                }
                .tag(Tab.View1)
                .id(reset)        // reset on changed !!
            
            View2()
                .tabItem {
                    Label("View2", systemImage: "")
                }
                .tag(Tab.View2)
        }
    }
}
Exploratory answered 1/2, 2021 at 17:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.