如何实现“向右拖动”解除导航堆栈中的视图控制器?

默认情况下,如果从屏幕的左边缘向右拖动,它将拖动ViewController并将其从堆栈中取出。

我想把这个function扩展到整个屏幕。 当用户在任何地方拖动,我想同样的事情发生。

我知道我可以实现一个滑动右手势,只需调用self.navigationController?.popViewControllerAnimated(true)

但是,没有“拖”的动作。 我希望用户能够右键拖动视图控制器,就好像它是一个对象,揭示下面的内容。 而且,如果拖到50%以上,请将其解雇。 (看看instagram,看看我的意思。)

在这里输入图像说明

在Github做了一个演示项目
https://github.com/rishi420/SwipeRightToPopController

我用过UIViewControllerAnimatedTransitioning协议

从文档:

//用于百分比驱动的交互式转换,以及容器控制器…

在控制器的视图中添加了一个UIPanGestureRecognizer 。 这是手势的动作:

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

脚步:

  1. 计算视图上拖动的百分比
  2. .Begin:指定要执行哪个segue并分配UINavigationController委托。 InteractiveTransitioning将需要委托
  3. .Changed: UpdateInteractiveTransition与百分比
  4. .Ended:如果拖动50%或更多或更高的速度,则继续保持转换,否则取消
  5. .Cancelled, .Failed:取消转换

参考文献:

  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

您需要调查UINavigationController的interactivePopGestureRecognizer属性。

这里有一个类似的问题与示例代码来钩住这个。

UINavigationController interactivePopGestureRecognizer在iOS7中工作exception

您可以使用滑动右手势达到此目的:

 override func viewDidLoad() { super.viewDidLoad() var swipeRight = UISwipeGestureRecognizer(target: self, action: "popViewController:") swipeRight.direction = UISwipeGestureRecognizerDirection.Right self.view.addGestureRecognizer(swipeRight) } func popViewController(gesture: UIGestureRecognizer) { if let swipeGesture = gesture as? UISwipeGestureRecognizer { switch swipeGesture.direction { case UISwipeGestureRecognizerDirection.Right: self.navigationController.popViewControllerAnimated(true) default: break } } }