Search code examples
swiftswiftuinavigationbarnavigationview

SwiftUI hiding a navigation bar only when looking at ContentView


I have a Content file and am hiding the navigation bar because it takes up space and pushes elements down. One of the buttons in the ContentView redirects (using a navigation link) to another view. In this other view, the navigationBar is still hidden....for simplicity sake, I'll cut out some of the code from ContentView:

//this is the view that looks "fine" (i.e. the navigation bar takes up no space)
struct ContentView: View {
    @State private var isPresentedSettings = false
    var body: some View {
        NavigationView {
            ZStack {
                VStack {
                    SettingsButton(isPresentedSettings: $isPresentedSettings)
                }
            }.navigationBarTitle("").navigationBarHidden(true)
        }
    }
}

//this is the button that pulls up the settings page view
struct SettingsButton: View {
    @Binding var isPresentedSettings: Bool
    var body: some View {
        NavigationLink (destination: SettingsPageView(isPresentedSettings: 
        self.$isPresentedSettings)) {
            Button(action: { self.isPresentedSettings.toggle() }, label: { Text("Button") })
        }
    }
}

//This is the view that should have a navigationbar but it doesn't
struct SettingsPageView: View {
    @Binding var isPresentedSettings: Bool
    var body: some View {
        NavigationView {
            VStack {
                Text("This is a view")
            }.navigationBarTitle("Settings", displayMode: .inline)
        }
    }
}

Also...there may have been typos because I just copied the code over from another computer. Sorry and thank you in advance!


Solution

  • Firstly, you don't need to have this isPresentedSettings variable for presenting a NavigationLink.

    NavigationLink(destination: SettingsPageView()) {
        Text("Button")
    }
    

    And there should be only one NavigationView in your view hierarchy.

    This is how your final code can look like:

    struct ContentView: View {
        @State private var navBarHidden = true
    
        var body: some View {
            NavigationView {
                ZStack {
                    VStack {
                        SettingsButton(navBarHidden: $navBarHidden)
                    }
                }
                .navigationBarHidden(navBarHidden)
            }
        }
    }
    
    struct SettingsButton: View {
        @Binding var navBarHidden: Bool
    
        var body: some View {
            NavigationLink(destination: SettingsPageView(navBarHidden: $navBarHidden)) {
                Text("Show View")
            }
        }
    }
    
    struct SettingsPageView: View {
        @Binding var navBarHidden: Bool
    
        var body: some View {
            VStack {
                Text("This is a view")
            }
            .navigationBarTitle("Settings", displayMode: .inline)
            .onAppear {
                self.navBarHidden = false
            }
            .onDisappear {
                self.navBarHidden = true
            }
        }
    }