Custom back button for NavigationView's navigation bar in SwiftUI

LinusGeffarth picture LinusGeffarth · Jun 13, 2019 · Viewed 32.7k times · Source

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)

Answer

Ashish picture Ashish · Aug 21, 2019

TL;DR

Use this to transition to your view:

NavigationLink(destination: SampleDetails()) {}

Add this to the view itself:

@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

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

presentationMode.wrappedValue.dismiss()

Full code

From a parent, navigate using NavigationLink

 NavigationLink(destination: SampleDetails()) {}

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

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)
    }
}