iOS 全局修改UINavigation 后退按钮

简介: 快两年没有更新blog了,现在有点时间随便写点东西吧。做iOS项目中,可能会经常遇到要定制后退按钮的情况,比如把后退按钮的title固定为“返回”(修改title对后面push的vc生效),比如用图片,这时候大家一般会选择添加一个vc的基类,因为这个问题其实很简单,随便做点什么都能解决,今天我用另一种优雅的方法来解决这个问题。

快两年没有更新blog了,现在有点时间随便写点东西吧。

做iOS项目中,可能会经常遇到要定制后退按钮的情况,比如把后退按钮的title固定为“返回”(修改title对后面push的vc生效),比如用图片,这时候大家一般会选择添加一个vc的基类,因为这个问题其实很简单,随便做点什么都能解决,今天我用另一种优雅的方法来解决这个问题。


默认iOS7的后退按钮是一个箭头+文字,如果想只要箭头的话,只要把title设为空就行了,我先用普通的类别方式来做,首先添加类别:

@implementation UINavigationItem (CustomBackButton)


@end

覆盖原有的方法: 

-(UIBarButtonItem *)backBarButtonItem{

    return [[UIBarButtonItem allocinitWithTitle:@"" 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 allocinitWithTitle:@"" 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开发
iOS MFMessageComposeViewController不显示取消按钮,导航条上白色,无取消按钮,无法返回应用...
iOS MFMessageComposeViewController不显示取消按钮,导航条上白色,无取消按钮,无法返回应用...
73 0
|
9天前
|
JavaScript 前端开发 iOS开发
ios样式开关按钮jQuery插件
ios样式开关按钮jQuery插件
34 7
|
1月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
56 1
|
2月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
58 5
|
7月前
|
iOS开发
iOS13.6.1系统XR手机图文按钮显示不全问题
iOS13.6.1系统XR手机图文按钮显示不全问题
74 0
|
7月前
按钮的image图片是非圆角,直接对UIButton设置圆角,iOS13系统没有圆角效果的问题及解决方案
按钮的image图片是非圆角,直接对UIButton设置圆角,iOS13系统没有圆角效果的问题及解决方案
52 0
|
监控 Android开发 iOS开发
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮
150 0
|
移动开发 JavaScript Android开发
iOS12网页视频播放点击全屏按钮会导致闪退
iOS12网页视频播放点击全屏按钮会导致闪退
320 0
|
开发工具 iOS开发 git
iOS开发 - 类似美团选商品页,从按钮上往上滑动,tableview依然响应,点击按钮,按钮也可响应
iOS开发 - 类似美团选商品页,从按钮上往上滑动,tableview依然响应,点击按钮,按钮也可响应
219 0
iOS开发 - 类似美团选商品页,从按钮上往上滑动,tableview依然响应,点击按钮,按钮也可响应
|
iOS开发
iOS开发 - 解析tabbar中的凸起按钮
iOS开发 - 解析tabbar中的凸起按钮
415 0
iOS开发 - 解析tabbar中的凸起按钮