'SwiftUI - navigationBarBackButtonHidden - swipe back gesture?

if I set a custom Back Button (which everyone wants, hiding the ugly text ;-) ) and using .navigationBarBackButtonHidden, the standard Swipe Back gesture on the navigation controller does not work. Is there a way to get this back and having a custom back button?

For Example:

NavigationView {
    NavigationLink(destination: DummyViewer())
     {
       Text("Go to next view"
    } 
 }
struct DummyViewer: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
    var body: some View {
        Text("Hello, World!").navigationBarBackButtonHidden(true)
            .navigationBarItems(leading:
                Button(action: { self.presentationMode.wrappedValue.dismiss()}) {
                    Text("Custom go back")
                }
        )
    }
}

If I do so, I cannot swipe back to the previous view, seems the gesture is then disabled... How to get it back?

BR Steffen



Solution 1:[1]

Nothing I found about creating a custom NavigationView worked but I found that by extending UINavigationController I was able to have a custom back button and the swipe back gesture.

extension UINavigationController: UIGestureRecognizerDelegate {
    override open func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }
}

Solution 2:[2]

If it's still actual, here I answered, how to set custom back button and save swipe back gesture.

Solution 3:[3]

I would like to integrate the answer given by Nick Bellucci to make the code also works in other circumstances, e.g. when the child view of the NavigationView is a ScrollView, or a View that is listening for Drag gestures.

extension UINavigationController: UIGestureRecognizerDelegate {
    override open func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    } 

    // To make it works also with ScrollView
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        true
    }
}

Solution 4:[4]

You can set the title to an empty string. So back bar button title will be empty:

struct ContentView: View {

    var body: some View {

        NavigationView {

            NavigationLink(destination: Text("Here you are")) {

                Text("Next").navigationBarTitle("")
            }
        }
    }
}

You can set the title onAppear or onDisappear if you need to.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nick Bellucci
Solution 2 Hrabovskyi Oleksandr
Solution 3 Niccolò Fontana
Solution 4 Mojtaba Hosseini