自定义全屏返回手势

代码地址如下:
http://www.demodashi.com/demo/11971.html

使用分类,入侵性低,直接拖动到项目中,一句代码都不用写,自动生效

演示效果

目录结构

原理

.h文件

/// 自定义全屏拖拽返回手势
@property (nonatomic, strong, readonly) UIPanGestureRecognizer *popGestureRecognizer;

定义单个控制器取消手势方法

- (void)cancleHMFullScreenPopGesRec:(BOOL)cancle;

.m文件

一、引入头文件#import <objc/runtime.h>

二、定义手势代理类

    // 判断是否是根控制器,如果是,取消手势
    if (self.navigationController.viewControllers.count <= 1) {
        return NO;
    }
    
    // 如果正在转场动画,取消手势
    if ([[self.navigationController valueForKey:@"_isTransitioning"] boolValue]) {
        return NO;
    }
    
    // 判断手指移动方向
    CGPoint translation = [gestureRecognizer translationInView:gestureRecognizer.view];
    if (translation.x <= 0) {
        return NO;
    }
    if (self.isCancle) {
        return NO;
    }
    return YES;
}

三、在NCPopGestureRecognizer的类实现中

在load方法中交换navVC的push方法和自定义的方法实例

+ (void)load {
    
    Method originalMethod = class_getInstanceMethod([self class], @selector(pushViewController:animated:));
    Method swizzledMethod = class_getInstanceMethod([self class], @selector(hm_pushViewController:animated:));
    
    method_exchangeImplementations(originalMethod, swizzledMethod);
}

取消的方法调用上边自定义类的属性赋值

- (void)cancleHMFullScreenPopGesRec:(BOOL)cancle {
  
    [self hm_fullScreenPopGestureRecognizerDelegate].isCancle = cancle;
    
}

自定义push方法和手势
根据kvc取值拿到 target 和action添加到自定义手势
并禁用系统交换手势,设置手势代理为自定义类

- (void)hm_pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    
    if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.popGestureRecognizer]) {
        [self.interactivePopGestureRecognizer.view addGestureRecognizer:self.popGestureRecognizer];
        
        NSArray *targets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
        id internalTarget = [targets.firstObject valueForKey:@"target"];
        SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
        
        self.popGestureRecognizer.delegate = [self hm_fullScreenPopGestureRecognizerDelegate];
        [self.popGestureRecognizer addTarget:internalTarget action:internalAction];
        
        // 禁用系统的交互手势
        self.interactivePopGestureRecognizer.enabled = NO;
    }
    
    if (![self.viewControllers containsObject:viewController]) {
        [self hm_pushViewController:viewController animated:animated];
    }
}

用runtime给分类添加属性绑定

- (HMFullScreenPopGestureRecognizerDelegate *)hm_fullScreenPopGestureRecognizerDelegate {
    HMFullScreenPopGestureRecognizerDelegate *delegate = objc_getAssociatedObject(self, _cmd);
    if (!delegate) {
        delegate = [[HMFullScreenPopGestureRecognizerDelegate alloc] init];
        delegate.navigationController = self;
        
        objc_setAssociatedObject(self, _cmd, delegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return delegate;
}
- (UIPanGestureRecognizer *)popGestureRecognizer {
    UIPanGestureRecognizer *panGestureRecognizer = objc_getAssociatedObject(self, _cmd);
    
    if (panGestureRecognizer == nil) {
        panGestureRecognizer = [[UIPanGestureRecognizer alloc] init];
        panGestureRecognizer.maximumNumberOfTouches = 1;
        
        objc_setAssociatedObject(self, _cmd, panGestureRecognizer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return panGestureRecognizer;
}
```自定义全屏返回手势

> 代码地址如下:<br>http://www.demodashi.com/demo/11971.html



> 注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

posted on 2018-03-05 17:06  demo例子集  阅读(599)  评论(0编辑  收藏  举报

导航