UIPanGestureRecognizer to pop UIViewController
Asked Answered
Z

3

1

I'm wondering if it is actually possible to use a UIPanGestureRecognizer on a pushed UIViewController to achieve a similar behaviour like in the Telegram messenger chat view (and a lot of other popular Apps), where you can simply swipe to the right from anywhere on the screen to get back to the menu (or any other View Controller that initially pushed the one we are looking at).
I tried this code:

    @objc func swipeLeft(_ sender: UIPanGestureRecognizer) {
    let point = sender.translation(in: view)
    containerView.center = CGPoint(x: point.x > 0 ? view.center.x + point.x : view.center.x, y: view.center.y)
    if sender.state != .ended { return }

    if containerView.center.x < view.frame.width / 2 {
        dismissSelf()
    }
    else {
        UIView.animate(withDuration: 0.2) {
            self.containerView.center = self.view.center
        }
    }
}

and a UIPanGestureRecognizer, which does work nicely if you presented your ViewController but not when it is pushed. At least not how it is right now.

Right now, you see a black view and that's also what you see in the "Debug View Hirachy" at the bottom of a pushed UIViewController.

Any help is appreciated!

Zeringue answered 14/6, 2019 at 21:52 Comment(0)
E
2

I think what you are looking for is already built-in with the interactivePopGestureRecognizer

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true

if you want to make some custom or different animation then I think you need to check transitions. Here's a good article to make custom transitions: https://medium.com/swift2go/simple-custom-uinavigationcontroller-transitions-fdb56a217dd8

Eu answered 14/6, 2019 at 23:54 Comment(3)
But that one only goes from the screen edge. I already have it set up but would like to additionally be able to swipe starting from anywhere on the screen.Zeringue
if you check the article, you can handle the custom transition on any gesture recognizer you like.Eu
Thanks I solved it using the article! I replaced the UIScreenEdgePanGestureRecognizer with a UIPanGestureRecognizer.Zeringue
E
1

No need of handling pan gesture. you could just embed your view in a navigation controller, and it will provide such behaviour (swipe to go back).

Then you could also hide the navigation bar if you dont want to see it.

The user can also remove the topmost view controller using the back button in the navigation bar or using a left-edge swipe gesture.

https://developer.apple.com/documentation/uikit/uinavigationcontroller

// Hide the Navigation Bar
self.navigationController?.setNavigationBarHidden(true, animated: animated)

// Show the Navigation Bar
self.navigationController?.setNavigationBarHidden(false, animated: animated)
Enchain answered 18/6, 2019 at 9:28 Comment(0)
B
0

I've just created a Pod to have this Telegram/Instagram-like Pan-to-pop behavior on the navigation controller.

You can see it here

It allows the user to:

  • Pan-to-pop normally from the left edge (like every normal UINavigationController)
  • Pan-to-pop from the center where there is no scrollView or other panGesture that interferes
  • Pan-top-pop on top of any scrollView if they are at offset.x = 0 (so it behaves like Instagram)

All of this while keeping all the default functionality of the navigation controller.

To install it with CocoaPods just include the pod in the Podfile:

pod 'EZCustomNavigation', '1.0.0'

And to use it just use EZNavigationController instead of the default UINavigationController and it should just work.

Burnsed answered 9/11, 2019 at 12:11 Comment(2)
What did you use to implement it? / What is the core principle that your custom class builds upon?Zeringue
@Zeringue it's mainly a subclass of UINavigationController, so everything just works as the base one, with a custom animator (that looks exactly like the default one) and a pan gesture that handles the interactive transition. The hardest part was to allow panning also on top of scrollView, and to distinguish which scrollView was embedded in my navigation controller and which weren't, to let anyone use it without doing any work. That's done with the responderChain (if my NavigationController is in the responder chain, than the scrollView itself is embedded in it). Hope this helps.Burnsed

© 2022 - 2024 — McMap. All rights reserved.