标签:
今天在做项目的时候遇到一点小问题,后来自己解决了,也顺便思考了一下更深层次的东西,在这里分享一下~~
很多app的要求所有的返回按钮的title都是“返回”,如果上一层题目文字太多,下一层的返回按钮文字就会显示不完全,而且这样可以使软件显得整洁。
最普通的想法,A界面的navigationItem.backBarButtonItem修改的是B(A的下一级)界面的返回按钮,所以可以写一个BaseViewController
,让所有的UIViewController
继承它,像这样
- (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil]; }
思路是:在开启程序时,使用Method Swizzling
,将系统自带的backBarButtonItem
方法替换成我们自定义的方法。
具体实现就是创建个 UINavigationItem + BackItem
的类别,当系统执行+load
方法时,将backBarButtonItem
方法和myCustomBackButton
方法交换,利用iOS关联方法(objc_getAssociatedObject,objc_setAssociatedObject)
在static
区创建个backItemButton
用来展示。这个方法的好处就是将类别导入到工程里不用任何代码就可以实现,上代码吧:
+(void)load{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method originalMethodImp = class_getInstanceMethod(self, @selector(backBarButtonItem)); Method destMethodImp = class_getInstanceMethod(self, @selector(myCustomBackButton)); method_exchangeImplementations(originalMethodImp, destMethodImp); }); } static char kCustomBackButtonKey; -(UIBarButtonItem *)myCustomBackButton{ UIBarButtonItem *item = [self myCustomBackButton]; if (item) { return item; } item = objc_getAssociatedObject(self, &kCustomBackButtonKey); if (!item) { item = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:NULL]; objc_setAssociatedObject(self, &kCustomBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return item; } - (void)dealloc { objc_removeAssociatedObjects(self); }
最开始我的方案是实现UINavigationController
的代理判断是否是栈底,如果不是就修改leftBarButtonItem
的样式。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { UIViewController *root = navigationController.viewControllers[0]; if (root != viewController) { UIBarButtonItem *itemleft = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"backBtn"] style:UIBarButtonItemStylePlain target:self action:@selector(popAction:)]; viewController.navigationItem.leftBarButtonItem = itemleft; } } - (void)popAction:(UIBarButtonItem *)barButtonItem { [self.navigationController popViewControllerAnimated:YES]; }
但iOS7.0
出了之后,这并不是一个好的解决方案。因为iOS7.0
之后如果把backItemButton
替换成leftItemButon
,interactivePopGestureRecognizer
手势就没有了。虽然可以使用
self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;
这个方法和上边‘替换返回按钮的文字’方法二大致一样,这句话要替换:
item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"] style:UIBarButtonItemStylePlain target:nil action:nil];
这句话要加上,用来去除系统自带的返回按钮上的尖脚号。
[[UINavigationBar appearance] setBackIndicatorImage:[[UIImage alloc]init]];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[[UIImage alloc] init]];
技术上的问题其实有好多方法可以去解决,而且在效率相差不大的情况下,关键是我们的使用习惯,所以整理一下现在的思路,方便以后使用。
标签:
原文地址:http://www.cnblogs.com/LeoTai/p/5456705.html