swiftnavigationviewswiftui

Custom back button for NavigationView's navigation bar in SwiftUI


I want to add a custom navigation button that will look somewhat like this:

desired navigation back button

Now, I've written a custom BackButton view for this. When applying that view as leading navigation bar item, by doing:

.navigationBarItems(leading: BackButton())

...the navigation view looks like this:

current navigation back button

I've played around with modifiers like:

.navigationBarItem(title: Text(""), titleDisplayMode: .automatic, hidesBackButton: true)

without any luck.

Question

How can I...

  1. set a view used as custom back button in the navigation bar? OR:
  2. programmatically pop the view back to its parent?
    When going for this approach, I could hide the navigation bar altogether using .navigationBarHidden(true)

Solution

  • TL;DR

    Use this to transition to your view:

    NavigationLink(destination: SampleDetails()) {}
    

    Add this to the view itself:

    @Environment(\.dismiss) private var dismiss
    

    Then, in a button action or something, dismiss the view:

    dismiss()
    

    Full code

    From a parent, navigate using NavigationLink

     NavigationLink(destination: SampleDetails()) {}
    

    In DetailsView hide navigationBarBackButton and set custom back button to leading navigationBarItem,

    struct SampleDetails: View {
        @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    
        var btnBack : some View { Button(action: {
            self.presentationMode.wrappedValue.dismiss()
            }) {
                HStack {
                Image("ic_back") // set image here
                    .aspectRatio(contentMode: .fit)
                    .foregroundColor(.white)
                    Text("Go back")
                }
            }
        }
        
        var body: some View {
                List {
                    Text("sample code")
            }
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(leading: btnBack)
        }
    }