您的位置:首页 > 产品设计 > UI/UE

UINavigationController 自定义返回按钮导致返回手势失效解决办法

2016-12-06 16:55 429 查看
之前项目中遇到了,在这里记录下,网络找了很多,大部分写的不完成,基本不能实现。

第一种方法,很简单,重新签订协议:

首先,在要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呢?
需要用运行时,遍历所有的属性找到



代码分析:
class CustomNavigationController: UINavigationController {


override func viewDidLoad() {

super.viewDidLoad()


// 1.取出手势&view

guard let gesture = interactivePopGestureRecognizer else { return }

gesture.isEnabled = false

let gestureView = gesture.view


// 2.获取所有的target

let target = (gesture.value(forKey: "_targets") as? [NSObject])?.first

guard let transition = target?.value(forKey: "_target") else { return }

let action = Selector(("handleNavigationTransition:"))


// 3.创建新的手势

let popGes = UIPanGestureRecognizer()

popGes.maximumNumberOfTouches = 1

gestureView?.addGestureRecognizer(popGes)

popGes.addTarget(transition, action: action)

}


override func pushViewController(_ viewController: UIViewController, animated: Bool) {

viewController.hidesBottomBarWhenPushed = true

super.pushViewController(viewController, animated: animated)

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: