自定义全局返回按钮,保留侧滑返回手势

用导航控制器 自定义返回按钮时侧滑返回手势会失效

通常我们会在自定义了返回按钮的控制器中去开启手势和设置代理
如果要修改很多页面的话很麻烦
所以用runtime进行全局修改。

新建UIViewController的类别

在.m文件中导入#import <objc/runtime.h>然后添加如下代码就可以了:

+ (void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
//      把viewDidLoad、viewDidAppear:、viewWillDisappear:替换成自定义的方法
        Method viewDidLoadImp = class_getInstanceMethod(self, @selector(viewDidLoad));
        Method cbi_viewDidLoadImp = class_getInstanceMethod(self, @selector(cbi_viewDidLoad));
        method_exchangeImplementations(viewDidLoadImp, cbi_viewDidLoadImp);
        
        Method viewDidAppearImp = class_getInstanceMethod(self, @selector(viewDidAppear:));
        Method cbi_viewDidAppearImp = class_getInstanceMethod(self, @selector(cbi_viewDidAppear:));
        method_exchangeImplementations(viewDidAppearImp, cbi_viewDidAppearImp);
        
        Method viewWillDisappearImp = class_getInstanceMethod(self, @selector(viewWillDisappear:));
        Method cbi_viewWillDisappearImp = class_getInstanceMethod(self, @selector(cbi_viewWillDisappear:));
        method_exchangeImplementations(viewWillDisappearImp, cbi_viewWillDisappearImp);
    });
}

- (void)leftItemClick {
    [self.navigationController popViewControllerAnimated:YES];
}

//自定义的方法,进行按钮自定义、手势的开关、手势代理设置
- (void)cbi_viewDidLoad {
    
    //不在一级界面时添加自定义按钮
    if ([self.navigationController.viewControllers count] > 1) {
        //在这里自定义你需要的全局返回按钮
        UIBarButtonItem * leftItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"返回"] style:UIBarButtonItemStylePlain target:self action:@selector(leftItemClick)];
        self.navigationItem.leftBarButtonItem = leftItem;
        
    }
    
    [self cbi_viewDidLoad];
}

- (void)cbi_viewDidAppear:(BOOL)animated {
    
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        if ([self.navigationController.viewControllers count] > 1) {
            self.navigationController.interactivePopGestureRecognizer.enabled = YES;
            self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
        } else {
            self.navigationController.interactivePopGestureRecognizer.enabled = NO;
        }
    }
    
    [self cbi_viewDidAppear:animated];
}

- (void)cbi_viewWillDisappear:(BOOL)animated {
    
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
        self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }
    [self cbi_viewWillDisappear:animated];
}

在.m的这个方法中修改你的全局自定义按钮:

- (void)cbi_viewDidLoad {
    
    //不在一级界面时添加自定义按钮
    if ([self.navigationController.viewControllers count] > 1) {
        //在这里自定义你需要的全局返回按钮
        UIBarButtonItem * leftItem = [[UIBarButtonItem alloc]
                                        initWithImage:[UIImage imageNamed:@"返回"] 
                                        style:UIBarButtonItemStylePlain 
                                        target:self 
                                        action:@selector(leftItemClick)];

        self.navigationItem.leftBarButtonItem = leftItem;
        
    }
    
    [self cbi_viewDidLoad];
}

因为是全局影响的不用导入头文件就会生效。

如果想某个页面不用侧滑手势返回
就在该控制器的viewDidAppear:做如下操作关闭侧滑手势:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}

如果要改变某个控制器的返回按钮,直接在viewDidLoad中自定义leftBarButtonItem就好了,会覆盖全局的。

代码下载

GitHub:ZBCustomBackItem
下载后直接拖入项目中即可

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容