用导航控制器 自定义返回按钮时侧滑返回手势会失效
通常我们会在自定义了返回按钮的控制器中去开启手势和设置代理
如果要修改很多页面的话很麻烦
所以用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
下载后直接拖入项目中即可