iOS设置自定义BackBarButtonItem

BackBarButtonItem 层级结构

首先我们看一下返回按钮的导航栏视图的结构层次,因为导航栏的视图加载以及初始化跟viewController的view不一样,不能再veiwDidLoad中去观察(viewWillAppear中也不行)要在viewDidLoad中才可以看到完整的导航栏视图结构层次。我们可以在一个有去掉文字的返回按钮控制器的viewDidApper中打上断点然后在控制台执行:

po [[UIWindow keyWindow] recursiveDescription]

打印结果:

; layer = >
   | ; layer = >
   |    | >
   |    |    | >
   |    |    |    | >
   |    |    |    |    | >
   |    |    |    |    |    | >
   |    | >
   |    |    | <_UIBarBackground: 0x7fc56e410a90; frame = (0 -44; 414 88); userInteractionEnabled = NO; layer = >
   |    |    |    | >
   |    |    |    | >
   |    |    |    |    | <_UIVisualEffectBackdropView: 0x7fc56e706750; frame = (0 0; 414 88); autoresize = W+H; userInteractionEnabled = NO; layer = >
   |    |    |    |    | <_UIVisualEffectSubview: 0x7fc56e707810; frame = (0 0; 414 88); autoresize = W+H; userInteractionEnabled = NO; layer = >
   |    |    | <_UINavigationBarLargeTitleView: 0x7fc56e4125f0; frame = (0 0; 0 50); clipsToBounds = YES; hidden = YES; layer = >
   |    |    |    | >
   |    |    | <_UINavigationBarContentView: 0x7fc56e411c80; frame = (0 0; 414 44); layer = >
   |    |    |    | >
   |    |    | <_UINavigationBarModernPromptView: 0x7fc56e608a20; frame = (0 0; 0 50); alpha = 0; hidden = YES; layer = >

设置BackBarButtonItem

1.文字偏移法

#pragma mark - 自定义系统自带的backBarButtomItem
// 去掉系统默认自带的文字(上一个控制器的title),修改系统默认的样式(一个蓝色的左箭头)为自己的图片
-(void)customBackBarButtonItem {
// 去掉文字
// 自定义全局的barButtonItem外观
UIBarButtonItem *barButtonItemAppearance = [UIBarButtonItem appearance];
// 将文字减小并设其颜色为透明以隐藏
[barButtonItemAppearance setTitleTextAttributes:@{NSFontAttributeName: [UIFont systemFontOfSize:0.1], NSForegroundColorAttributeName: [UIColor clearColor]} forState:UIControlStateNormal];

// 设置图片
// 获取全局的navigationBar外观
UINavigationBar *navigationBarAppearance = [UINavigationBar appearance];
// 获取原图
UIImage *image = [[UIImage imageNamed:@"navigationbar_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 修改navigationBar上的返回按钮的图片,注意:这两个属性要同时设置
navigationBarAppearance.backIndicatorImage = image;
navigationBarAppearance.backIndicatorTransitionMaskImage = image;
}

缺点:打开相册等,系统自带的导航条右侧的取消按钮也是透明的,看不见了

2.文字透明法

- (void)setNaviBack{

UINavigationBar * navigationBar = [UINavigationBar appearance];

//返回按钮的箭头颜色

[navigationBar setTintColor:[UIColor colorWithRed:0.984 green:0.000 blue:0.235 alpha:1.000]];

//设置返回样式图片

UIImage *image = [UIImage imageNamed:@"navi_back"];

image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

navigationBar.backIndicatorImage = image;

navigationBar.backIndicatorTransitionMaskImage = image;

UIBarButtonItem *buttonItem = [UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil];

UIOffset offset;

offset.horizontal = - 500;

offset.vertical =  - 500;

[buttonItem setBackButtonTitlePositionAdjustment:offset forBarMetrics:UIBarMetricsDefault];

}

缺点:
1.导航条上的返回按钮 的 相应区域 还是原来那么大 没有变为图片的大小
2.第一个界面的 title 过长 会影响 跳转到的第二界面 的 title
因为没有去改变系统的backBarButtonItem,所以位置是没有变的。
3.设置 setBackButtonTitlePositionAdjustment还会导致一个问题,就是在做分享或者是支付,跳转其他APP(eg:支付宝,微信)之后,返回自己的APP的时候,会出现屏幕闪动的BUG,建议不要使用这个方法来做.

3.综合方案

以下代码写在自定义的导航控制器中
1.替换系统默认返回图片
- (void)viewDidLoad {
[super viewDidLoad];

self.delegate = self;

// 自定义返回图片(在返回按钮旁边) 这个效果由navigationBar控制
[self.navigationBar setBackIndicatorImage:[UIImage imageNamed:@"NavBack"]];
[self.navigationBar setBackIndicatorTransitionMaskImage:[UIImage imageNamed:@"NavBack"]];
}


2.去掉文字
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewControllers.count > 0) {
viewController.hidesBottomBarWhenPushed = YES;
}

// 去掉系统backBarButtonItem的默认显示效果
// 这个效果由控制器控制(A push B 则在A中设置)
/***
1、如果B视图有一个自定义的左侧按钮(leftBarButtonItem),则会显示这个自定义按钮;

2、如果B没有自定义按钮,但是A视图的backBarButtonItem属性有自定义项,则显示这个自定义项;

3、如果前2条都没有,则默认显示一个后退按钮,后退按钮的标题是A视图的标题。
*/
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:NULL];
viewController.navigationItem.backBarButtonItem = item;

[super pushViewController:viewController animated:animated];
}

你可能感兴趣的:(iOS设置自定义BackBarButtonItem)