关于更改导航栏背景色为纯色的另一种思路

这篇文章,我主要是想提供另外一种思路,来变更一下UINavigationController的颜色。
我们知道,调用navigationBar的setBarTintColor这个方法是可以实现改变导航栏颜色的,但是苹果大神是如何实现这个效果的呢,我们不妨来猜一下。首先我们来看一个正常的导航栏的层级视图。


关于更改导航栏背景色为纯色的另一种思路_第1张图片
正常导航栏层级视图.png

再看看我们使用了setBarTintColor这个方法之后的层级视图


关于更改导航栏背景色为纯色的另一种思路_第2张图片
设置之后的层级视图.png

神奇的来了,居然是在UIBackdropView上再加了2个View,而且是覆盖在_UIBackdropEffectView上面,而这个_UIBackdropEffectView就是毛玻璃效果那个View,是不是觉得很神奇!我TM当时也震颤了一下!现在也没有想通为什么苹果要这样做,希望有大神解释一下。

好了,接来下就说一下我的思考过程,顺便也记录一下我走的弯路。
首先,我的想法绝对不是增加一个View去覆盖,所以我就想到了改变上面的某个View的背景色,让navigationBar看起来像那么回事。
于是我想到了更改navigationBar的titleView。
通过各种设置,我达到了预期的效果。
1.自定义一个View

@interface YHCustomTitleView : UIView
@end
@implementation YHCustomTitleView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
    }
    return self;
}
//解决左右各10个像素左右的空白
- (void)setFrame:(CGRect)frame {
    [super setFrame:CGRectMake(0, 0, self.superview.bounds.size.width, self.superview.bounds.size.height)];
}
@end

2.替换titleView

YHCustomTitleView * view = [[YHCustomTitleView alloc] initWithFrame:(CGRectMake(0, 0, SCREEN_WIDTH, 64))];
    view.backgroundColor = [UIColor orangeColor];
    self.navigationItem.titleView = view;
关于更改导航栏背景色为纯色的另一种思路_第3张图片
更换titleView的效果

3.发现坑了。。。。。麻痹。。。原来的返回按钮点不动了!!!!而且当你立刻看当前的层级视图时,根本找不到问题。
于是我就pop到这个页面,查看层级视图,发现原来返回按钮被覆盖住了

关于更改导航栏背景色为纯色的另一种思路_第4张图片
更改titleView后的层级视图.png

4.如果还要一根筋走下去,剩下的工作就是将这个自定义的titleView作为navigationBar,隐藏掉系统的返回按钮,自定义按钮上去了。这样一来,问题就更过多了,比如左划无法pop等等。

这个时候,我发现,如果我们就改它的_UINavigationBarBackgroud这个View的背景颜色,不就行了。浏览一下navigationBar的.h文件,发现并没有提供这个View,不过没关系,宝宝有runtime大法!我们看看navigationBar到底藏了哪些不愿意我们改的东西!


关于更改导航栏背景色为纯色的另一种思路_第5张图片
貌似发现了什么.png

到底是不是它!拿出来看看!

就是你,不要跑.png

好!事情发展到这一步,离结束就不远了,改掉它的背景色后发现还有个毛玻璃效果,问题不大!因为我们已经拿到了这个view,而effectView恰恰是_UIBackdropView的子视图,另外一个子视图是UIImageView,其实就是那条著名的阴影。影藏掉_UIBackdropView就ok了,上代码。

UIView * tempview = [self.navigationController.navigationBar valueForKey:@"_backgroundView"];
    tempview.backgroundColor = [UIColor redColor];
    for (UIView * subView in tempview.subviews) {
        if (![subView isKindOfClass:[UIImageView class]]) {
            subView.hidden = YES;
        }
    }

目前还没有发现这种方法会引起的bug,如果过段时间还没有发现,我就把它搞到项目中,应对产品经理搞得幺蛾子了!

你可能感兴趣的:(关于更改导航栏背景色为纯色的另一种思路)