iOS 全局修改UINavigation 后退按钮
2014-03-28 23:55
465 查看
快两年没有更新blog了,现在有点时间随便写点东西吧。
做iOS项目中,可能会经常遇到要定制后退按钮的情况,比如把后退按钮的title固定为“返回”(修改title对后面push的vc生效),比如用图片,这时候大家一般会选择添加一个vc的基类,因为这个问题其实很简单,随便做点什么都能解决,今天我用另一种优雅的方法来解决这个问题。
默认iOS7的后退按钮是一个箭头+文字,如果想只要箭头的话,只要把title设为空就行了,我先用普通的类别方式来做,首先添加类别:
@implementation UINavigationItem (CustomBackButton)
@end覆盖原有的方法:
-(UIBarButtonItem *)backBarButtonItem{
return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:NULL];}这种方式乍一看可以达到目的,运行起来看也是那么回事,但是如果你在某个vc里面用:
接下来我们使用Swizzling。首先添加load方法交换实现:
+(void)load{
static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method originalMethodImp = class_getInstanceMethod(self, @selector(backBarButtonItem)); Method destMethodImp = class_getInstanceMethod(self, @selector(myCustomBackButton_backBarbuttonItem)); method_exchangeImplementations(originalMethodImp, destMethodImp); });}objective c的运行时编程是非常强大的,这里我们仅仅只是交换一下两个方法的实现而已,接下来实现myCustomBackButton_backBarButtonItem(为了防止命名冲突,一般我们会这么命名)。
在此之前,我们需要知道,vc的navigationItem.backBarButtonItem默认是nil的,而且只有在nil的时候,系统才会把vc的title当作后退文字来使用:
static char kCustomBackButtonKey;
-(UIBarButtonItem *)myCustomBackButton_backBarbuttonItem{ UIBarButtonItem *item = [self myCustomBackButton_backBarbuttonItem]; if (item) { return item; } item = objc_getAssociatedObject(self, &kCustomBackButtonKey); if (!item) { item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:NULL]; objc_setAssociatedObject(self, &kCustomBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return item;}第一行访问self的myCustomBarButton_backBarButtonItem其实是访问原始的backBarButtonItem,这么做的目的是针对vc自己对navigationItem.backBarButtonItem赋值的情况,如果不加上这个处理的话,vc自己对navigationItem.backBarButtonItem的自定义就会被忽略掉,我们需要保证:默认情况下就是只显示箭头而不带文字,如果有某个vc自己对backBarButtonItem赋值的话,就按vc自定义的来显示,这样我们才能总是得到真正想要的item。
我们用对象关联把self和item关联起来,用的时候直接取即可。最后可以加上:
- (void)dealloc {
objc_removeAssociatedObjects(self);}
做iOS项目中,可能会经常遇到要定制后退按钮的情况,比如把后退按钮的title固定为“返回”(修改title对后面push的vc生效),比如用图片,这时候大家一般会选择添加一个vc的基类,因为这个问题其实很简单,随便做点什么都能解决,今天我用另一种优雅的方法来解决这个问题。
默认iOS7的后退按钮是一个箭头+文字,如果想只要箭头的话,只要把title设为空就行了,我先用普通的类别方式来做,首先添加类别:
@implementation UINavigationItem (CustomBackButton)
@end覆盖原有的方法:
-(UIBarButtonItem *)backBarButtonItem{
return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:NULL];}这种方式乍一看可以达到目的,运行起来看也是那么回事,但是如果你在某个vc里面用:
self.navigationItem.backBarButtonItem想取得backBarButtonItem然后修改默认title的话,就不行了,这样一来就违背了我们使用类别的初衷:不影响原有的代码及使用方式。
接下来我们使用Swizzling。首先添加load方法交换实现:
+(void)load{
static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Method originalMethodImp = class_getInstanceMethod(self, @selector(backBarButtonItem)); Method destMethodImp = class_getInstanceMethod(self, @selector(myCustomBackButton_backBarbuttonItem)); method_exchangeImplementations(originalMethodImp, destMethodImp); });}objective c的运行时编程是非常强大的,这里我们仅仅只是交换一下两个方法的实现而已,接下来实现myCustomBackButton_backBarButtonItem(为了防止命名冲突,一般我们会这么命名)。
在此之前,我们需要知道,vc的navigationItem.backBarButtonItem默认是nil的,而且只有在nil的时候,系统才会把vc的title当作后退文字来使用:
static char kCustomBackButtonKey;
-(UIBarButtonItem *)myCustomBackButton_backBarbuttonItem{ UIBarButtonItem *item = [self myCustomBackButton_backBarbuttonItem]; if (item) { return item; } item = objc_getAssociatedObject(self, &kCustomBackButtonKey); if (!item) { item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:NULL]; objc_setAssociatedObject(self, &kCustomBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return item;}第一行访问self的myCustomBarButton_backBarButtonItem其实是访问原始的backBarButtonItem,这么做的目的是针对vc自己对navigationItem.backBarButtonItem赋值的情况,如果不加上这个处理的话,vc自己对navigationItem.backBarButtonItem的自定义就会被忽略掉,我们需要保证:默认情况下就是只显示箭头而不带文字,如果有某个vc自己对backBarButtonItem赋值的话,就按vc自定义的来显示,这样我们才能总是得到真正想要的item。
我们用对象关联把self和item关联起来,用的时候直接取即可。最后可以加上:
- (void)dealloc {
objc_removeAssociatedObjects(self);}
UPDATED:
忘记了很重要的一点:要导入<objc/runtime.h>相关文章推荐
- iOS 全局修改UINavigation 后退按钮
- iOS 全局修改UINavigation 后退按钮
- iOS 全局修改UINavigation 后退按钮
- IOS:修改NavigationController的后退按钮标题
- iOS 使用使用Swizzling 全局修改Navigation的返回按钮
- iOS 利用self.navigationItem.backBarButtonItem修改后退按钮文字
- iOS 在NavigationController 基类中 自定义全局后退按钮 且 开启手势后退
- ios UINavigationController 修改返回按钮
- IOS:修改NavigationController的后退按钮标题
- IOS:修改NavigationController的后退按钮标题
- iOS UINavigationController修改导航栏标题、按钮文字以及背景的颜色
- iOS 全局竖屏 单个viewcontroller点击按钮支持横屏
- iOS - 关于导航两侧按钮距离左右侧边距的修改
- iOS 修改navigation的back按钮
- iOS修改导航栏的返回按钮的内容
- iOS 修改导航栏的返回按钮的内容
- iOS小技巧 - 全局修改状态栏的样式为白色
- iOS---自定义返回按钮 (全局设置)
- iOS中全局悬浮按钮,类似IPhone中的AssistiveTouch
- 修改按钮上图片的大小-iOS