在开发当中,我们不得不要将导航栏的左边返回按钮自定义成不同的样式,但是一当我们自定义样式后,系统默认的 pop 手势就失效了,那么我们该如何做呢?其实这个问题网上也有很多答案,但是每一个答案都非常坑,我都不得不吐槽一下了,老是将问题复杂化,不懂装懂,最讨厌这些人了,好了,我们继续开始:
1.自定义一个导航栏,并重写它的 ViewDidLoa()方法
class CMNavgationController: UINavigationController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
unowned let weakSelf = self
if self.respondsToSelector("interactivePopGestureRecognizer"){
self.interactivePopGestureRecognizer.delegate = weakSelf
self.delegate = weakSelf
}
}
当导航栏一向应 "interactivePopGestureRecognizer" 这个默认响应的一个手势,我们就重新设置手势的代理不再是系统的 UINavagtionController,而是我们的代理 "CMNavgationController" 这个导航控制器 , 而且这个导航控制器的代理也必须为它自己,因为这个导航控制器等一下还要监听它自己的 navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) 这个代理方法
-----------------------------------------分割线-----------------------------------
2.重写导航栏的 pushViewController 方法
override func pushViewController(viewController: UIViewController, animated: Bool) {
if viewControllers.count > 0 {
if self.respondsToSelector("interactivePopGestureRecognizer"){
self.interactivePopGestureRecognizer.enabled = false;
}
}
super.pushViewController(viewController, animated: true)
}
重写 push 方法最主要的目的是让这个 pop 手势在 push 的时候变为不可用,因为可能在 push 过程中用户很快的进行了左滑动,那么就会造成 pop 栈中的混乱,导致画面卡顿,所以为了避免这个情况,我们必须要设置在 Push 过程中禁止这个手势的响应
-----------------------------------------分割线-----------------------------------
3.设置导航栏代理方法,监听导航栏是否 显示完毕
extension CMNavgationController: UINavigationControllerDelegate {
func navigationController(navigationController: UINavigationController, didShowViewController
viewController: UIViewController, animated: Bool) {
if (self.viewControllers.count == 1) {
self.interactivePopGestureRecognizer.enabled = false;
}else{
self.interactivePopGestureRecognizer.enabled = true;
}
}
}
这个方法主要是监听导航栏是否显示完毕,当显示完毕的时候我们要进行一个判断,因为当控制器ViewController 数量为1的时候,用户如果进行了右滑,但问题是当前控制器数量只有一个,那个这个方法 POP 什么呢?根本就没法 POP 嘛,也会造成了 pop 栈中的混乱,导致画面一直卡顿,所以我们也要进行一个判断,判断控制器数量只有一个的时候,我们就禁止了这个手势,反之则开启
-----------------------------------------分割线-----------------------------------
4。在普通的控制器中进行自定义左边的返回按钮
class HomeViewController:UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var button = UIButton(frame: CGRectMake(0, 0, 80, 40))
button.setImage(UIImage(named: image), forState: UIControlState.Normal)
button.addTarget(self, action: "back", forControlEvents: UIControlEvents.TouchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: button)
}
func back(){
self.popViewControllerAnimated(true)
}
}
好了,到这里就一齐都结束了,完美解决了这个手势,但是如果需要更漂亮的手势的话就要自己自定义 POP 手势了,而 苹果公司也给我们提供了这些方法,在这里我留着下次再说了,写这篇文章完全为了平坑,网上的人乱写一通,不想更多的人去踩坑了。
talk is chep,show me the code