如何实现“向右拖动”解除导航堆栈中的视图控制器?
默认情况下,如果从屏幕的左边缘向右拖动,它将拖动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 } }
脚步:
- 计算视图上拖动的百分比
-
.Begin:
指定要执行哪个segue并分配UINavigationController
委托。InteractiveTransitioning
将需要委托 -
.Changed:
UpdateInteractiveTransition与百分比 -
.Ended:
如果拖动50%或更多或更高的速度,则继续保持转换,否则取消 -
.Cancelled, .Failed:
取消转换
参考文献:
您需要调查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 } } }