全屏右滑返回的一些事一些情

96
Fasa
2015.09.12 00:10* 字数 365

前因

人活一辈子,总要遇上一些事情。
拿我自己来说
便是实现iOS全屏右滑返回。

我开始参考的是啊崢的文章
【8行代码教你搞定导航控制器全屏滑动返回效果】

实现起来却是遇上了不少问题,因为手势代理方法做的判断不够完善,还有好几个情况下触发手势导致bug出现。

总的来说有三种情况下手势不应该执行:

  • 当前controller是rootViewController时
  • pop动画正在进行时
  • 左滑时

另外。
该文采取的办法是对navigationController自带的interactivePopGestureRecognizer下手,禁用interactivePopGestureRecognizer,给interactivePopGestureRecognizer的delegate换上自定义的UIPanGestureRecognizer。

是否有更简单的办法?有的。

// 更换interactivePopGestureRecognizer的delegate
// 这里设置为navigationController自己
    self.interactivePopGestureRecognizer.delegate = self;
// 自带的边缘返回手势的类是UIScreenEdgePanGestureRecognizer,只负责edge部分
// 那么换成包容心更强的UIPanGestureRecognizer
    object_setClass(self.interactivePopGestureRecognizer, [UIPanGestureRecognizer class]);

可是还是喜欢拿来主义。
于是在github上找到:
sunnyxxx的FDFullscreenPopGesture

sunnyxxx已经封装得很完美了,完全AOP。在其手势代理方法中,除了上面提到的三种情况,还增加了两种情况,通过设置controller的两个属性控制手势。

  • fd_interactivePopDisabled:可单独关闭某个controller的滑动返回手势
  • fd_interactivePopMaxAllowedInitialDistanceToLeftEdge:自定义手势范围。

拿来主义真好。
我把代码改了下,对delegate下手,代码如下。

//    if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.fd_fullscreenPopGestureRecognizer]) {
//        
//        // Add our own gesture recognizer to where the onboard screen edge pan gesture recognizer is attached to.
//        [self.interactivePopGestureRecognizer.view addGestureRecognizer:self.fd_fullscreenPopGestureRecognizer];
//
//        // Forward the gesture events to the private handler of the onboard gesture recognizer.
//        NSArray *internalTargets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
//        id internalTarget = [internalTargets.firstObject valueForKey:@"target"];
//        SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
//        self.fd_fullscreenPopGestureRecognizer.delegate = self.fd_popGestureRecognizerDelegate;
//        [self.fd_fullscreenPopGestureRecognizer addTarget:internalTarget action:internalAction];
//
//        // Disable the onboard gesture recognizer.
//        self.interactivePopGestureRecognizer.enabled = NO;
//    }
    
    if ([self.interactivePopGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
        object_setClass(self.interactivePopGestureRecognizer, [UIPanGestureRecognizer class]);
        self.interactivePopGestureRecognizer.delegate = self.fd_popGestureRecognizerDelegate;
    }

后果

再也不需要自定义手势+截图实现返回转场那种老方法了。

Public
Gupao