Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I implement "drag right to dismiss" a View Controller that's in a navigation stack?

Tags:

By default, if you drag right from the left edge of the screen, it will drag away the ViewController and take it off the stack.

I want to extend this functionality to the entire screen. When the user drags right anywhere, I'd like the same to happen.

I know that I can implement a swipe right gesture and simply call self.navigationController?.popViewControllerAnimated(true)

However, there is no "dragging" motion. I want the user to be able to right-drag the view controller as if it's an object, revealing what's underneath. And, if it's dragged past 50%, dismiss it. (Check out instagram to see what I mean.)

like image 550
TIMEX Avatar asked Feb 14 '16 06:02

TIMEX


People also ask

How do I remove a view controller from navigation stack?

Use this code and enjoy: NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray: self. navigationController. viewControllers]; // [navigationArray removeAllObjects]; // This is just for remove all view controller from navigation stack.

How do you dismiss the presenting view controller?

When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it.


1 Answers

enter image description here

Made a demo project in Github
https://github.com/rishi420/SwipeRightToPopController

I've used UIViewControllerAnimatedTransitioning protocol

From the doc:

// This is used for percent driven interactive transitions, as well as for container controllers ...

Added a UIPanGestureRecognizer to the controller's view. This is the action of the gesture:

func handlePanGesture(panGesture: UIPanGestureRecognizer) {      let percent = max(panGesture.translationInView(view).x, 0) / view.frame.width      switch panGesture.state {      case .Began:         navigationController?.delegate = self         navigationController?.popViewControllerAnimated(true)      case .Changed:         percentDrivenInteractiveTransition.updateInteractiveTransition(percent)      case .Ended:         let velocity = panGesture.velocityInView(view).x          // Continue if drag more than 50% of screen width or velocity is higher than 1000         if percent > 0.5 || velocity > 1000 {             percentDrivenInteractiveTransition.finishInteractiveTransition()         } else {             percentDrivenInteractiveTransition.cancelInteractiveTransition()         }      case .Cancelled, .Failed:         percentDrivenInteractiveTransition.cancelInteractiveTransition()      default:         break     } } 

Steps:

  1. Calculate the percentage of drag on the view
  2. .Begin: Specify which segue to perform and assign UINavigationController delegate. delegate will be needed for InteractiveTransitioning
  3. .Changed: UpdateInteractiveTransition with percentage
  4. .Ended: Continue remaining transitioning if drag 50% or more or higher velocity else cancel
  5. .Cancelled, .Failed: cancel transitioning


References:

  1. UIPercentDrivenInteractiveTransition
  2. https://github.com/visnup/swipe-left
  3. https://github.com/robertmryan/ScreenEdgeGestureNavigationController
  4. https://github.com/groomsy/custom-navigation-animation-transition-demo
like image 199
Warif Akhand Rishi Avatar answered Nov 11 '22 16:11

Warif Akhand Rishi