动态修改NavigationBar的颜色


转: http://www.jianshu.com/p/6f3bc1da18f3


动态修改NavigationBar的颜色
字数785 阅读2269 评论4 喜欢9
如果我们想动态的修改NavigationBar的颜色会肿么做呢?
首先我们想到的肯定是在UISrollView的delegate方法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

根据当前的contentOffset更新navigationBar的backgroundColor即可.

思路
首先想到的是最常用的[UINavigationBar appearance],我们一般会在AppDelegate中使用它对navigationBar进行统一的设置。但是如果试一下,会发现在scrollViewDidScrollView中调用它并不能动态地改变navigationBar的颜色,原因是: iOS应用出现变化时,视图会进入一个窗口,它不能改变已经再一个窗口的外观。

我们换一个方法试试看,直接修改UINavigationBar的backgroudColor:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UIColor *color = [UIColor redColor];
CGFloat offsetY = scrollView.contentOffset.y;
if (offsetY > 0) {
    CGFloat alpha = 1 - ((64 - offsetY) / 64);
    self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:alpha];
} else {
     self.navigationController.navigationBar.backgroundColor = [color colorWithAlphaComponent:0];
        }
}
然后发现,怎么是。。。。。有一半咋没有颜色 ????这是神马情况???


通过reveal查看其中的层级结构,发现NavigationBar上面有一个_UINavigationBarBackground的遮盖,正是它决定了navigationBar的背景色。


那我们把这个view拿到,删除不就可以了么?继续尝试。

我们通过打印 self.navigationController.navigationBar.subviews看到navigationBar上有两个子控件。

"<_UINavigationBarBackground: 0x7fed90f43990; frame = (0 -20; 414 64); opaque = NO; autoresize = W;                     userInteractionEnabled = NO; layer = <CALayer: 0x7fed90f36a90>>",
"<_UINavigationBarBackIndicatorView: 0x7fed90d053f0; frame = (0 11.6667; 13 21); alpha = 0; opaque = NO;             userInteractionEnabled = NO; layer = <CALayer: 0x7fed90dc6e50>>"
我们可以通过遍历把 _UINavigationBarBackground 拿到并删除即可

for (UIView *view in self.navigationController.navigationBar.subviews) {
    if ([view isKindOfClass:NSClassFromString(@"_UINavigationBarBackground")]) {
        [view removeFromSuperview];
    }
}
然后发现这样就可以了,不过状态栏还是白色的啊~~~


这时我们改变下状态栏的颜色就好了,要修改状态栏的颜色比较麻烦,那我们可以直接在navigationBar上加上一层遮罩就好

UIView *overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width,20)];
overlay.backgroundColor = [UIColor redColor];
[self.navigationController.navigationBar insertSubview:overlay atIndex:0];
不过这么干的话,那就要修改两个控件颜色。。。。这样修改起来非常的麻烦,有没有什么好点的方法呢????

换一个思路
考虑到继承UINavigationBar使用起来会非常不便,我们决定用Category来实现,首先定义我们的category:

@interface UINavigationBar (BackgroundColor)
- (void)lt_setBackgroundColor:(UIColor *)backgroundColor;
@end
我们可以使用associatedObject将overlay动态地绑定到UINavigationBar的instance上,当调用lt_setBackgroundColor的时候,我们只要更新这个overlay就可以了

   static char overlayKey;
@implementation UINavigationBar (BackgroundColor)


- (UIView *)overlay
{    return objc_getAssociatedObject(self, &overlayKey);
}

- (void)setOverlay:(UIView *)overlay
{
objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)lt_setBackgroundColor:(UIColor *)backgroundColor
{    
    if (!self.overlay) {
    [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    [self setShadowImage:[UIImage new]];             
    self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, 64)];
    [self insertSubview:self.overlay atIndex:0];  
}   
        self.overlay.backgroundColor = backgroundColor;
}
@end
最后在scrollViewDidScroll中,我们就可以动态地修改UINavigationBar的backgroundColor了:

[self.navigationController.navigationBar lt_setBackgroundColor:[color colorWithAlphaComponent:alpha]];

这个方法是参考了 LTNavigationBar 第三方类库,这类库已经给我们封装好了这些方法,使用起来非常简单

详情请点这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值