iOS-自定义导航栏后侧滑返回失效,且控制器添加ScrollView后侧滑返回失效

iOS-自定义导航栏后侧滑返回失效

从iOS7开始,系统为UINavigationController提供了一个interactivePopGestureRecognizer用于右滑返回(pop),但是,如果自定了当前视图控制器leftBarButtonItem,或自定义导航栏后该手势就失效了。

解决方法:

自定义UINavigationController,实现其代理方法:

#import "DYNavigationController.h"

@interface DYNavigationController () 

@property (nonatomic,strong) id popDelegate;

@end

@implementation DYNavigationController

- (void)viewDidLoad {
    [super viewDidLoad];
    //代理
    self.popDelegate = self.interactivePopGestureRecognizer.delegate;
    self.delegate = self;
}

#pragma UINavigationControllerDelegate方法
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    //实现滑动返回功能
    //清空滑动返回手势的代理就能实现
    self.interactivePopGestureRecognizer.delegate =  viewController == self.viewControllers[0]? self.popDelegate : nil;
}

@end

控制器添加ScrollView后侧滑返回失效

大概思路就是,既然你拦截了我的手势,那我就要想办法让手势传递下去,不被你拦截,所以最后的解决办法就是对Scrollview加个Category,重写它代理的方法,让手势能够传递下去

解决方法:

自定义UIScrollView的分类,重写代理方法:

#import "UIScrollView+DY.h"

@implementation UIScrollView (DY)

#define KScreenHeight [UIScreen mainScreen].bounds.size.height //屏幕的高度
#define KScreenWidth [UIScreen mainScreen].bounds.size.width // 屏幕的宽度
//是否支持多手势触发,返回YES,则可以多个手势一起触发方法,返回NO则为互斥.
//是否允许多个手势识别器共同识别,一个控件的手势识别后是否阻断手势识别继续向下传播,默认返回NO;如果为YES,响应者链上层对象触发手势识别后,如果下层对象也添加了手势并成功识别也会继续执行,否则上层对象识别后则不再继续传播
//一句话总结就是此方法返回YES时,手势事件会一直往下传递,不论当前层次是否对该事件进行响应。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    
    if ([self panBack:gestureRecognizer]) {
        return YES;
    }
    return NO;
    
}

//location_X可自己定义,其代表的是滑动返回距左边的有效长度
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {
    
    //是滑动返回距左边的有效长度
    int location_X = 0.15*KScreenWidth;
    
    if (gestureRecognizer == self.panGestureRecognizer) {
        UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
        CGPoint point = [pan translationInView:self];
        UIGestureRecognizerState state = gestureRecognizer.state;
        if (UIGestureRecognizerStateBegan == state ||UIGestureRecognizerStatePossible == state) {
            CGPoint location = [gestureRecognizer locationInView:self];
            
            //这是允许每张图片都可实现滑动返回
            //int temp1 = location.x;
            //int temp2 = KScreenWidth;
            //NSInteger XX = temp1 % temp2;
            //if (point.x > 0 && XX < location_X) {
            //    return YES;
            //}
            //下面的是只允许在第一张时滑动返回生效
            if (point.x > 0 && location.x < location_X && self.contentOffset.x <= 0) {
                return YES;
            }
        }
    }
    return NO;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([self panBack:gestureRecognizer]) {
        return NO;
    }
    return YES;
    
}

@end

你可能感兴趣的:(iOS-自定义导航栏后侧滑返回失效,且控制器添加ScrollView后侧滑返回失效)