ios 导航栏透明及颜色动态变化

让导航栏透明有个简单的方法,就是将一张透明的png图片设置为navgationBar的背景图片,但是这样做的话就不能动态调整其颜色了,下面我们来研究如何用代码来控制其颜色。

新建个工程NavDemo

将根视图控制器设置为带导航控制器的ViewController:

self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];

添加一个scrollView来根据其滚动的距离动态调整导航栏的颜色,为了让显示更直观我们加了一张背景图片

    [self setTitle:@"主页"];

    self.view.backgroundColor = [UIColor whiteColor];

    

    

    UIScrollView *scrollview = [[UIScrollView alloc] initWithFrame:self.view.bounds];

    scrollview.contentSize = CGSizeMake(0, 1000);

    scrollview.delegate = self;

    [self.view addSubview:scrollview];

    


    UIImageView  *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 160)];

    imageView.contentMode = UIViewContentModeScaleAspectFill;

    imageView.clipsToBounds = YES;

    imageView.backgroundColor = [UIColor whiteColor];

    imageView.image = [UIImage imageNamed:@"image.png"];

    [scrollview addSubview:imageView];


我们先用常规的方法来为导航栏设置背景颜色看看

self.navigationController.navigationBar.backgroundColor = [UIColor orangeColor];


运行demo,发现导航栏并没有变为设定的颜色,但可以隐约看到有背景色,这时我们打开xcode的视图调试功能来看看究竟

ios 导航栏透明及颜色动态变化_第1张图片

可以看到我们已经成功的为UINavgationBar设置了背景色,但是被上层的其它视图给挡住了,那上面的三个视图究竟是什么鬼,先来查看一下

ios 导航栏透明及颜色动态变化_第2张图片


底下是一个_UINavigationBarBackground类型的视图

ios 导航栏透明及颜色动态变化_第3张图片


中间是个_UIBackdropView 类型的视图


ios 导航栏透明及颜色动态变化_第4张图片

最外面是个_UIBackdropEffectView类型的视图

并且他们之间的层级关系已经很清楚明了了



现在明白原因后就好解决了,我们可以为其中三个中的任意一个设置背景色即可

但笔者在测试中发现设置上面两个的背景色是没用的,因为它们都自动转为了navgationBar的背景,依旧被挡住了,大家有时间可以试下

现在只能从_UINavigationBarBackground视图入手了,设置它的背景色,然后将上面两个视图隐藏

声明一个全局的_navBackView视图来记录_UINavigationBarBackground,用递归循环遍历

navigationBar的子视图

 [self getBackView:self.navigationController.navigationBar];


-(void)getBackView:(UIView*)superView

{

    if ([superView isKindOfClass:NSClassFromString(@"_UINavigationBarBackground")])

    {   

        _navBackView = superView;

        //在这里可设置背景色

        _navBackView.backgroundColor = [UIColor orangeColor];

    }

    else if ([superView isKindOfClass:NSClassFromString(@"_UIBackdropView")])

    { 

          

         //_UIBackdropEffectView_UIBackdropView的子视图,这是只需隐藏父视图即可

          superView.hidden = YES;

    }


    for (UIView *view in superView.subviews)

    {

        [self getBackView:view];

    }

}


运行demo,发现背景色设置成功,下面就是动态调整其颜色了

在scrollView的滑动代理里不断改变_navBackView的颜色

-(void)scrollViewDidScroll:(UIScrollView *)scrollView

{

    CGFloat alaph = 1 - (scrollView.contentOffset.y + 64) / 64.0;

    

    alaph = alaph < 0 ? 0 : alaph;

    _navBackView.backgroundColor = [[UIColor orangeColor] colorWithAlphaComponent:alaph];

}


现在,一个可以动态调整导航栏颜色的demo就完成啦,但细心的朋友会发现还有个小的瑕疵,那就是导航栏下方还有条细线没去掉ios 导航栏透明及颜色动态变化_第5张图片

有了前面的调试经验后,这个也好解决,先找到它ios 导航栏透明及颜色动态变化_第6张图片


苹果居然用的是个imageView,我之前还以为是label呢。好了,现在移除它就完美了

把递归函数修改下

-(void)getBackView:(UIView*)superView

{

    if ([superView isKindOfClass:NSClassFromString(@"_UINavigationBarBackground")])

    {

        //移除分割线

        for (UIView *view in superView.subviews)

        {

            if ([view isKindOfClass:[UIImageView class]])

            {

                [view removeFromSuperview];

            }

        }

        _navBackView = superView;

        //在这里可设置背景色

        _navBackView.backgroundColor = [UIColor orangeColor];

    }

    else if ([superView isKindOfClass:NSClassFromString(@"_UIBackdropView")])

    {

        //_UIBackdropEffectView_UIBackdropView的子视图,这是只需隐藏父视图即可

        superView.hidden = YES;

    }


    for (UIView *view in superView.subviews)

    {

        [self getBackView:view];

    }

    

}


ok,大功告成了

ios 导航栏透明及颜色动态变化_第7张图片

ios 导航栏透明及颜色动态变化_第8张图片

ios 导航栏透明及颜色动态变化_第9张图片




你可能感兴趣的:(ios 导航栏透明及颜色动态变化)