Swift - 导航控制器(navigationController)全屏滑动返回功能实现
作者:hangge | 2016-03-23 08:30
(本文代码已升级至Swift3)
navigationController(导航控制器)的view自带了滑动手势,只要在屏幕左侧向右拖动页面,就可以滑动返回到前面一个页面。但这个功能仅在屏幕左侧边缘滑动才能触发,我们可以稍作改造,让其支持全屏滑动返回。

1,全屏滑动返回实现原理
(1)系统自带的手势是 UIScreenEdgePanGestureRecognizer 类型对象,看名字就知道这个是屏幕边缘滑动手势。所以系统自带的滑动效果,自然只能实现侧边滑动。
(2)我们自己给导航控制器,添加一个全屏的滑动手势。然后用新添加的滑动手势,来调用系统实现的滑动返回功能(handleNavigationTransition 方法),这样就实现了全屏滑动功能。
(3)注意:我们还要禁止系统自带滑动手势,同时只有非根控制器才有滑动返回功能,根控制器没有。
2,效果图:

3,实现代码:
navigationController(导航控制器)的view自带了滑动手势,只要在屏幕左侧向右拖动页面,就可以滑动返回到前面一个页面。但这个功能仅在屏幕左侧边缘滑动才能触发,我们可以稍作改造,让其支持全屏滑动返回。

1,全屏滑动返回实现原理
(1)系统自带的手势是 UIScreenEdgePanGestureRecognizer 类型对象,看名字就知道这个是屏幕边缘滑动手势。所以系统自带的滑动效果,自然只能实现侧边滑动。
(2)我们自己给导航控制器,添加一个全屏的滑动手势。然后用新添加的滑动手势,来调用系统实现的滑动返回功能(handleNavigationTransition 方法),这样就实现了全屏滑动功能。
(3)注意:我们还要禁止系统自带滑动手势,同时只有非根控制器才有滑动返回功能,根控制器没有。
2,效果图:

3,实现代码:
import UIKit
class DetailViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let target = self.navigationController?.interactivePopGestureRecognizer!.delegate
let pan = UIPanGestureRecognizer(target:target,
action:Selector(("handleNavigationTransition:")))
pan.delegate = self
self.view.addGestureRecognizer(pan)
//同时禁用系统原先的侧滑返回功能
self.navigationController?.interactivePopGestureRecognizer!.isEnabled = false
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer:
UIGestureRecognizer) -> Bool {
if self.childViewControllers.count == 1 {
return false
}
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
全部评论(9)
航哥 谢谢啊 解决了燃眉之急啊
站长回复:不客气,我也很高兴能帮助到你。
请问一下,我按照你的方法实现之后;我的上一个A视图控制器隐藏了导航栏(需求如此),从B视图控制器滑动返回A视图控制器的时候,从B视图控制器的导航栏也隐藏了,这个问题有办法解决吗?谢谢
站长回复:这个应该跟本文讲的全屏滑动返回没什么关系把,因为A、B用的都是同一个导航控制器,那么在一个视图隐藏了另一个视图也是隐藏的。除非两个视图各自使用自己的导航栏。
rootViewController有冲突,如果在rootViewController里侧滑了 ,页面就不响应点击事件了
站长回复:我测试了下没问题啊,rootViewController里并没有添加滑动手势,不会影响页面的点击事件。
航哥,请教个问题,handleNavigationTransition 这个方法名是什么意思呢? 不用手动实现?
站长回复:这个是系统里的私有方法,我们不用手动实现,直接调用就可以了。
手势里面这个 handleNavigationTransition: 方法的实现呢?
站长回复:这个是系统自带的一个私有方法,不需要我们实现。我们只要调用就好了。
我用了怎么出现了 直接帮崩溃了呢
站长回复:我又测试了下,是没问题的呀。
快速垂直滑动,也会触发返回到上一层去
站长回复:这个应该是系统的bug,因为即使是什么都不改,使用默认的边缘滑动返回。只要视图移动出来后快速垂直滑动,也会触发返回上一层。
子页面如果有滚动条,好像冲突了
站长回复:不会冲突啊,可以滑动返回,同时子页面滚动条事件也会触发的。
航哥还真是巧了刚好这两天遇到侧滑返回的问题,来的真及时
站长回复:太好了:)