让导航栏透明有个简单的方法,就是将一张透明的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的视图调试功能来看看究竟
可以看到我们已经成功的为UINavgationBar设置了背景色,但是被上层的其它视图给挡住了,那上面的三个视图究竟是什么鬼,先来查看一下
底下是一个_UINavigationBarBackground类型的视图
中间是个_UIBackdropView 类型的视图
最外面是个_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就完成啦,但细心的朋友会发现还有个小的瑕疵,那就是导航栏下方还有条细线没去掉
把递归函数修改下
-(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,大功告成了