Home > Software design >  Multiple back buttons created when navigates to root screen in SwiftUI
Multiple back buttons created when navigates to root screen in SwiftUI

Time:01-27

say I create 3 screens in SwiftUI which contains a NavigationLink to the next screen. like, first screen navigates to 2nd screen. 2nd screen navigates to third. and the third screen navigates to the first screen. In this case even if I use NavigationView only once(in the first screen). I encountered that there's a back button forming when I navigate to 1st screen from the third screen. And it keeps adding up when I start to navigate from then on. I have tried to use .navigationBarBackButtonHidden(true). It hides it but the space taken by back button was still there. My code is similar to this:

struct FirstScreen: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: SecondScreen()) {
                    Text("Go to Second Screen")
                }
            }
        }
    }
}

struct SecondScreen: View {
    var body: some View {
        VStack {
            NavigationLink(destination: ThirdScreen()) {
                Text("Go to Third Screen")
            }
        }
    }
}

struct ThirdScreen: View {
    var body: some View {
        VStack {
            NavigationLink(destination: FirstScreen()) {
                Text("Go to First Screen")
            }
        }
    }
}

this is the image

CodePudding user response:

You're pushing the FirstScreen onto your navigation stack, but FirstScreen contains its own NavigationView. If you really want to keep pushing them on the stack, then move the NavigationView outside of FirstScreen.

struct ContentView: View {
    var body: some View {
        NavigationStack { // Use NavigationStack for iOS 16
            FirstScreen()
        }
    }
}

struct FirstScreen: View {
    var body: some View {
        VStack {
            NavigationLink(destination: SecondScreen()) {
                Text("Go to Second Screen")
            }
        }
    }
}

If you actually want to pop all the views off the stack and go back to FirstScreen you should use

init(path: Binding<NavigationPath>, etc)

Here's a simple example passing the path down the stack and resetting it to pop back to the root…

enum Screen {
    case two, three
}

struct ContentView: View {
    
    @State var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            VStack {

                // value gets appended to path
                NavigationLink("Go to Second Screen", value: Screen.two)
            }

            // Decides which screen to show for values in path
            .navigationDestination(for: Screen.self) { index in
                switch index {
                case .two:
                    SecondScreen(path: $path)
                case .three:
                    ThirdScreen(path: $path)
                }
            }
        }
    }
}

struct SecondScreen: View {
    @Binding var path: NavigationPath
    var body: some View {
        VStack {
            NavigationLink("Go to Third Screen", value: Screen.three)
        }
    }
}

struct ThirdScreen: View {
    @Binding var path: NavigationPath
    var body: some View {
        VStack {
            Button("Go to First Screen") {

                // reset the path to pop to root
                path = NavigationPath()
            }
        }
    }
}
  • Related