背景:App 主色调是 #2198C8(色 A), 但新增了一个模块在 push 到那个模块时需要改变颜色 为#25B4C7(色 B) ,然后再返回时依然是 #2198C8
用到的宏先列一下
#define IOS_VERSION [[[UIDevice currentDevice] systemVersion] floatValue] #define ColorSet(R,G,B,A) [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:A]
很简单的问题,项目的 ViewController 都是继承自一个自定义的基类,于是我在基类中写了一个方法,是这样的
-(void)setNavColor:(UIColor *)color{ if (IOS_VERSION >= 7.0) { [self.navigationController.navigationBar setBarTintColor:color]; } else{ [self.navigationController.navigationBar setTintColor:color]; } }
然后在需要改变颜色的ViewContoller(设为 C1)中调用
-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self setNavColor:ColorSet(37, 180, 199,1)];// 这个颜色即色 B }
在基类的 viewWillAppear 中调用
-(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; UIViewController *VC = self.navigationController.topViewController; if ([VC isKindOfClass:[AViewController class]] ||[VC isKindOfClass:[BViewContoller class]]) {// 在视图返回到 AViewContoller 或者 BViewController 时将颜色改回 A [self setNavColor:ColorSet(33, 152, 200, 1)];// 这个颜色即色 A } }
本以为这样就大功告成了(别担心,如果你是来找答案的,到这里就可以成功了,我这里情况有点特殊,感兴趣的可以看下去),可当我从 Apush C1,再pop 到 A,整个颜色变化都是对的,like this:
A(色 A) ↔ C1(色 B)
但是,当我从 A push到 C1,再push 到 C2,然后 pop 回 C1,pop 回 C2时变成了这样:
A(色A) → C1(色 B) → C2(色 B)
A( 色B,这里本应该是色 A) ← C1(色 B) ← C2(色 B)
查了好久的 Nav 层级关系,可只要进了 C2界面就不行,开始以为是 push 了两层的原因,后来发现 push 到第二层的页面只有是 C2才会这样,到别的页面是没有问题的,然后我这时才好好看了一下 C2的导航条,是这样的
为了做这样的效果,我们当时是去掉了导航条上自带的一条分割线,方法在下面,否则这个中间会有条线,所以我想应该是对 Bar 的这个处理有问题
PS:!!更新于2015-06-05 ,原来要去掉分割线只需要一句话即可
[bar setShadowImage:[[UIImage alloc]init]];
整个人都不好了,下面的是之前的坑代码
if ([self.navigationController.navigationBar respondsToSelector:@selector( setBackgroundImage:forBarMetrics:)]){ NSArray *list=self.navigationController.navigationBar.subviews; for (id obj in list) { if ([obj isKindOfClass:[UIImageView class]]) { UIImageView *imageView=(UIImageView *)obj; imageView.hidden=YES; } } UIImageView *imgView=[[UIImageView alloc] initWithFrame:CGRectMake(0, -20, 420, 64)]; [imgView setBackgroundColor:isLight?ColorSet(37,180,199,1):ColorSet(33, 152, 200, 1)];// 当时在修改时我已经在这里改了颜色的判断,但是却没有仔细看看这部分的实现,导致后面花费了大量的时间来调试这个问题 [self.navigationController.navigationBar addSubview:imgView]; [self.navigationController.navigationBar sendSubviewToBack:imgView]; }
看完这段代码你们或许明白了为什么我返回之后在试图中设置的 BarTintColor 没有效果了,因为在上面的For 循环中,NavigationBar 上的 imageView 被 Hidden,我们添加了一个自己得 imageView, 所以现在只需要将这个自己添加的imageView 去掉就好了,于是我在上面那段代码中为自行添加到 Bar 上的 imageView设置了一个 tag
imgView.tag = kSwitchImageTag;
然后在 C2视图消失时将这个自定义的背景 imgView 移除,并将 Bar自带的 imageView 的隐藏状态取消:
-(void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; for (UIView *view in self.navigationController.navigationBar.subviews) { if ([view isKindOfClass:[UIImageView class]]) { if (view.tag == kSwitchImageTag) { [view removeFromSuperview]; } else{ view.hidden = NO; } } } }
这样我得到了我想要的结果:
A(色A) ↔ C1(色 B) ↔ C2(色 B)
设置标题颜色字体,需要设置其他属性,只需要在字典中添加对应的 Key-Value 即可,如阴影等
NSDictionary *titleAttribute = @{NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue-CondensedBlack" size:20.0],UITextAttributeTextColor:[UIColor whiteColor]}; [[UINavigationBar appearance] setTitleTextAttributes:titleAttribute];
先更新这些,下次看到坑在填
----分割线----
用UINavigationController的时候有时候为了整体效果可能需要修改navigationBar颜色,这时候只要更改它的tintColor就行了
苹果默认效果
在代码中加入
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:68/255.f green:178/255.f blue:39/255.f alpha:0];
最终效果