之前项目中遇到了,在这里记录下,网络找了很多,大部分写的不完成,基本不能实现。
第一种方法,很简单,重新签订协议:
首先,在要push的控制器中加入以下代码:
override func viewDidLoad() { super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.delegate = self self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true }
并且遵守协议,然后既可以了。很简单。
还有一点记住,一般我们会将navigationController抽取成父类,如果是自定义的navigationController,也需要重新签订协议,否则还是没有返回手势,签订的方法如下:
override func viewDidLoad() {
let selector = NSSelectorFromString("interactivePopGestureRecognizer")
if self.responds(to: selector) { //重新签代理
self.interactivePopGestureRecognizer?.delegate = self
}
}这样就可以了。
第二种方法就是利用runtime,而且这个方法可以替换系统的pop手势,这样就不会仅仅限制于在边缘滑动返回了,具体做法如下:
- 首先,我们已经知道系统是有一个左滑手势
- 该左滑手势只能在左边缘滑动才会生效
- 但是该手势的View&target&action系统已经创建好了
- 我们可以自己创建一个手势,但是利用系统的View&target&action
- 问题?
- 1> 如果获取系统手势的View?
- 比如简单,因为可以直接获取interactivePopGestureRecognizer手势
- interactivePopGestureRecognizer.view即可获得
- 2> 如果获取target&action
- 该方式较为麻烦,需要使用KVC
- 通过某一些Key来获取可接
- 3> 通过哪些key呢?
- 需要用运行时,遍历所有的属性找到

- 需要用运行时,遍历所有的属性找到
- 1> 如果获取系统手势的View?
- 代码分析:
class CustomNavigationController: UINavigationController {override func viewDidLoad() {super.viewDidLoad()// 1.取出手势&viewguard let gesture = interactivePopGestureRecognizer else { return }gesture.isEnabled = falselet gestureView = gesture.view// 2.获取所有的targetlet target = (gesture.value(forKey: "_targets") as? [NSObject])?.firstguard let transition = target?.value(forKey: "_target") else { return }let action = Selector(("handleNavigationTransition:"))// 3.创建新的手势let popGes = UIPanGestureRecognizer()popGes.maximumNumberOfTouches = 1gestureView?.addGestureRecognizer(popGes)popGes.addTarget(transition, action: action)}override func pushViewController(_ viewController: UIViewController, animated: Bool) {viewController.hidesBottomBarWhenPushed = truesuper.pushViewController(viewController, animated: animated)}}
本文介绍两种在Swift中优化UINavigationController返回手势的方法。第一种方法通过重新设置代理来激活交互式弹出手势,确保其正常工作;第二种方法则利用Runtime替换默认的左滑返回手势,使其在屏幕任意位置滑动均可触发。
1086

被折叠的 条评论
为什么被折叠?



