iOS 全局修改UINavigationBar的返回按钮(适配 iOS 11)

这篇博客介绍了如何使用Objective-C的分类和runtime技术,全局修改iOS应用中UINavigationBar的默认返回按钮,以适配iOS 11及以上版本。通过重写getter和setter方法,确保在不同iOS版本下都能正确显示自定义的返回按钮。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

关于实现 App 全局统一样式的返回按钮,之前我们通过修改 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:] 来改变返回按钮中文字的偏移量,来实现隐藏文字的效果。但是改完后不是很满意,给大家两张图感受一下

←iOS10 ←iOS11

很明显,iOS 11以下,即使隐藏了文字,但是如果原本文字过长依旧会出现标题被挤到右侧的情况,而iOS 11,文字会从偏移后的位置出现或消失,正常动画时间下会有种很突兀的感觉。

正好在这时,产品在新项目中提了个要求,返回按钮默认文字为“返回”,而不再是隐藏。那么如果我们能够实现修改默认返回按钮文字,只要设置文字为@" "也能达到隐藏的目的,一举两得!那么就来试试能不能修改默认值吧。

思路


首先来看看UIBarButtonItem的相关Api,有没有能修改默认文字的方法。嗯……没找到………… 再找找UINavigationBar的相关Api,嗯……还是没找到………… 再看看UINavigationItem呢,嗯……还是找不到……接下来只能找产品改掉这个无理需求了

好吧,既然我们没法直接用苹果的Api搞定,那就自己来实现吧。很显然,无法调用外部Api就需要我们重写一些方法了,分类+runtime黑魔法是个很不错的方式。(什么?你说用继承?继承当然也可以实现,但是这种一点都不高大上,还要重新调整之前项目中旧代码的方式很明显第一时间就被我摒弃了。)所以接下来我们需要寻找关键的方法,然后通过重写来实现效果。

写之前我们先来回忆一下UINavigationBar中的UINavigationItemUIBarButtonItem:

UINavigationBar中的返回按钮以及标题、右侧按钮等控件都是由UINavigationItem属性来决定的,因此如果要修改这些内容,我们需要修改对应的UINavigationItem

在一个UINavigationController中的视图控制器做切换的时候,UINavigationBar是顶部导航栏视图,它始终是唯一的。大家都知道UINavigationController通过栈的方式来管理视图控制器的,同样UINavigationBar也是通过栈的方式来管理不同的UINavigationItem

UINavigationItem中的左侧按钮有两种:backBarButtonItemleftBarButtonItem,虽然都能改变左侧按钮但是区别较大。

  1. backBarButtonItem属性决定的是下一个视图返回当前视图的按钮,即设置A视图的UINavigationItem.backBarButtonItem,需要进入下一个B视图时,显示在左侧,不需要实现相应的点击事件;
  2. leftBarButtonItem属性可以直接更改当前视图导航栏的左侧按钮,替代掉前一个视图的backBarButtonItem,需要自己实现点击事件,同时会关闭侧滑手势。

既然我们要修改默认返回按钮,那么直接修改backBarButtonItem就可以了。

这里请注意,我们修改的是‘默认’值,也就是缺省值。如果代码中单独设置了backBarButtonItem,我们不能去改变这个值。

代码


说了这么多,直接来看实现:

  1. 新建UINavigationItem的分类
#import <UIKit/UIKit.h>

@interface UINavigationItem (BackItem)
@end
复制代码
  1. 导入runtime头文件,重写backBarButtonItem的getter方法
#import "UINavigationItem+BackItem.h"
#import <objc/runtime.h>

@implementation UINavigationItem (BackItem)

+(void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        Method originalMethodImp = class_getInstanceMethod(self, @selector(backBarButtonItem));
        Method destMethodImp = class_getInstanceMethod(self, @s
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值