Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI - navigationBarBackButtonHidden - swipe back gesture?

Tags:

swiftui

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

like image 202
sTOOs Avatar asked Dec 08 '19 11:12

sTOOs


2 Answers

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
    }
}
like image 200
Nick Bellucci Avatar answered Nov 19 '22 14:11

Nick Bellucci


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
    }
}
like image 13
Niccolò Fontana Avatar answered Nov 19 '22 12:11

Niccolò Fontana