NavigationController的侧滑返回功能

  1. 侧滑返回

    • NavigationController自从iOS7.0之后, 增加了一个滑动返回功能, 当push入一个控制器并且展示了这个控制器的View时, 除了点击左上方的返回按钮之外, 还可以向右滑动屏幕左边缘同样可以达到返回上一级界面的效果
    • 但是侧滑返回的问题就在于, 我们在项目中, 经常要使用自定义的返回按钮. 而当你使用了自定义按钮时, 你会发现侧滑返回效果挂掉了
  2. 侧滑返回的原理分析

    1. 手势:

      • 侧滑返回, 需要手指侧滑屏幕, 因此从这一点可以推断出来, 侧滑返回功能应该是一个UIGestureRecognizer

      • 进入UINavigationController的头文件中, 搜索UIGestureRecognizer, 这时我们会发现一个属性, 他就是用来管理导航控制器侧滑返回功能的手势

          // 这就是侧滑返回手势
          @property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) 
        
      • 通过查看文档, 可以了解到, 这个手势专门用来执行pop功能, 将栈顶控制器移除, 同时你还可以给当前这个View增加别的手势并且和侧滑返回手势绑定在一起(但是尽量不要这么用, 不觉得很反人类么...)

    2. 代理:

      • 这个手势是readonly, 也就是说你不能去修改他, 但是他在自定义按钮的时候确确实实的失效了. 而导致这个的真正原因, 可以让人联想到UIGestureRecognizerDelegate代理中的代理方法

          // 这个方法返回的BOOL值, 决定这个手势是否能够生效
          - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
        
      • 从这一点基本上就可以断定, 侧滑返回的代理, 检测到你自定义了返回按钮, 因此拦截了侧滑返回手势

      • 而我们要做的就是不让代理拦截他

  3. 恢复侧滑返回手势

    1. 首先, 我们要在自定义的NavigationController中, 当ViewDidLoad方法调用了, 为侧滑返回手势设置代理, 注意当前类要遵守协议

       self.interactivePopGestureRecognizer.delegate = self;
      
    2. 手动实现代理方法, 让手势可以使用

      • 在这里一定要注意: 如果你不判断当前子控制器的数量的话, 直接返回YES, 那么你的根控制器也会响应侧滑返回手势
      • 如果根控制器使用侧滑返回的话, 你的UI界面就会变为假死状态, 这是一个很严重的Bug, 因此一定要注意
        • (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
          return self.childViewControllers.count > 1;
          }

你可能感兴趣的:(NavigationController的侧滑返回功能)