解决自定义了导航条的返回按钮后,系统自带的滑动返回手势的失效问题.

背景介绍 : 在开发过程中,系统自带的某些功能,可能不满足我们的开发需求,所以常常需要我们自定义.当我们自定义导航条上的返回按钮之后,会发现系统自带的滑动返回手势处于失效状态,这是本章主要想解决的问题.

思路 : 既然自定义了导航条上的返回按钮,手势失效,说明系统内部是遵守了手势代理的,我们只需要打印出系统自带的手势就可以设置了.

    // 打印系统自带的手势
   NSLog(@"%@",self.interactivePopGestureRecognizer);
// 打印结果
 ;
 target= <(action=handleNavigationTransition:,
 target=<_UINavigationInteractiveTransition 0x7fb18a627a00>)>
  • 注意 : 在打印结果中,系统自带的手势只支持边缘滑动手势,它用的是 UIScreenEdgePanGestureRecognizer手势,只能在控制器的边缘才能出发手势的方法,这样,我们改一下,改成全屏都能出发滑动返回功能.
  • 我们来解读一下这个打印结果 :
  • 只要触发了UIScreenEdgePanGestureRecognizer这个手势,就会调用_UINavigationInteractiveTransition代理的
    只要触发UIScreenEdgePanGestureRecognizer,就会调用_UINavigationInteractiveTransition代理的
    handleNavigationTransition这个方法.
    说明 : _UINavigationInteractiveTransition代理的这个
    handleNavigationTransition方法有滑动返回的功能,只要我们创建新的手势设置这个代理,实现这个方法就可以实现滑动返回的功能了,
  • 下面我们照葫芦画瓢,实现全屏滑动返回.
  • 全屏滑动返回手势: UIPanGestureRecognizer
  • 代理: _UINavigationInteractiveTransition
  • 代理方法:handleNavigationTransition: (注意代理方法有参数,记得不要遗漏了冒号)
- (void)viewDidLoad {
   [super viewDidLoad];

   // 设置代理
   id target = self.interactivePopGestureRecognizer.delegate;

   // 创建手势
   UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];

   // 设置pan手势的代理
   pan.delegate = self;

   // 添加手势
   [self.view addGestureRecognizer:pan];

    // 将系统自带的手势覆盖掉
   self.interactivePopGestureRecognizer.enabled = NO;
}
  • 注意了 : 这里一定要设置pan.delegate = self, 不然程序会有假死的状况.(本章重点)

  • 做到这里,可以运行模拟器试一下, 会惊奇的发现,能全屏滑动返回了,但是,回到根控制器后,还是能继续滑动,这不是我们的想要的效果.所以还需要调用手势代理中的一个方法:即是否允许接收触摸事件.

// 表示的意思是:当挡墙控制器是根控制器了,那么就不接收触摸事件,只有当不是根控制器时才需要接收事件.
#pragma mark - UIGestureRecognizerDelegate
// 是否触发手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    return self.childViewControllers.count > 1;
}
  • 总结: 手势代理中还有很多好用的方法,比如: 是否允许同时接收多个手势事件等方法,都是开发中常用的,可以自己去手势代理的头文件中自学.

你可能感兴趣的:(解决自定义了导航条的返回按钮后,系统自带的滑动返回手势的失效问题.)