动态修改导航背景色和状态栏的颜色

一: 修改状态栏的颜色

定义了一个全局的属性记录偏移量,然后在滚动的代理方法中赋值并且调用UIViewController- (void)setNeedsStatusBarAppearanceUpdate方法。然后重写系统的- (UIStatusBarStyle)preferredStatusBarStyle方法。在这个方法中去改变状态栏的颜色。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    self.offset = scrollView.contentOffset.y;
    
    [self setNeedsStatusBarAppearanceUpdate];
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    
    if (self.offset > 50) {
        
        return UIStatusBarStyleDefault;
    }
    
    return UIStatusBarStyleLightContent;
}

- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {

    return UIStatusBarAnimationFade;
}

如果不是经过导航栏包装的控制器的话,到这里就可以实现根据偏移量修改状态栏的颜色了。如果你的控制器是经过导航控制器包装的,你需要自定义一个导航控制器继承自UINavigationController,重写
- (UIViewController *)childViewControllerForStatusBarStyle方法

- (UIViewController *)childViewControllerForStatusBarStyle {
    
    return self.topViewController;
}

让状态栏的颜色由控制器自己去决定。

二:修改导航栏的背景色

首先让导航栏是透明色,因此在 viewWillAppear中,

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
   
    //导航栏设置为透明
    [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    //去掉导航栏底部的黑线
    self.navigationController.navigationBar.shadowImage = [UIImage new];

  // 导航栏渐变色
    [self setNavBackColor:self.offset];
}

注意:在视图将要消失的时候,记得设置回来

-(void)viewWillDisappear:(BOOL)animated{
    [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
    [self.navigationController.navigationBar setShadowImage:nil];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    
    CGFloat offset = scrollView.contentOffset.y;
    
    self.offset = offset;
    
    [self setNavBackColor:self.offset];

}

#pragma mark --- 修改Navigation渐变色、状态栏颜色
- (void)setNavBackColor:(CGFloat)offset{
    
    CGFloat alpha = offset * 1 / 64.0;
    if (alpha >= 1) {
        alpha = 0.99;
    }
    UIColor *alphaColor = [UIColor colorWithWhite:1 alpha:alpha];
    UIImage *alphaImage = [UIImage imageWithColor:alphaColor];
    [self.navigationController.navigationBar setBackgroundImage:alphaImage forBarMetrics:UIBarMetricsDefault];
    
    // 修改状态栏的颜色
    [self setNeedsStatusBarAppearanceUpdate];
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    
    if (self.offset > 50) {
        
        return UIStatusBarStyleDefault;
    }
    
    return UIStatusBarStyleLightContent;
}

最后,如果要修改状态栏的颜色,记得:
定义一个导航控制器继承自UINavigationController,重写
- (UIViewController *)childViewControllerForStatusBarStyle方法

UIImage Category

+ (UIImage *)imageWithColor:(UIColor *)color {
    CGRect rect = CGRectMake(0, 0, 1.0f, 1.0f);
    // 开启位图上下文
    UIGraphicsBeginImageContext(rect.size);
    // 开启上下文
    CGContextRef ref = UIGraphicsGetCurrentContext();
    // 使用color演示填充上下文
    CGContextSetFillColorWithColor(ref, color.CGColor);
    // 渲染上下文
    CGContextFillRect(ref, rect);
    // 从上下文中获取图片
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    // 结束上下文
    UIGraphicsEndImageContext();
    return image;
}

参考:https://www.jianshu.com/p/d0a523659f08

推荐阅读更多精彩内容