导航栏动态渐变

首先可以自己新创建一个带导航栏的项目,跑起来后点击下方的如图所示

查看navigationBar视图层级.png

可以看到navigationBar的视图层级如下所示

navigationBar设置背景图前的视图层级.png

自己可以操作下给navigationBar设置个空image的图片,得到的视图层级如下所示

navigationBar设置背景图后的视图层级.png

我们知道给UIImageView设置一个空image的图片,那么UIImageView就相当于是一个透明的view,知道了这一点,那我们就可以直接对navigationBar的子视图UIBarBackground设置颜色或者透明度来是导航栏动态改变颜色及透明度了。

由层级图可知UIBarBackground是navigationBar的第一个子视图,我们可以在控制器定义一个属性类型为UIView的navTopView属性,以持有他方便后面修改他的颜色

@property (nonatomic, strong) UIView *navTopView;

可以在viewController的viewDidLoad里赋值

self.navTopView = self.navigationController.navigationBar.subviews.firstObject;
- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
    //去除导航栏黑线
    self.navigationController.navigationBar.shadowImage = [UIImage new];
}
//恢复导航栏
- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
    //恢复导航栏黑线
    self.navigationController.navigationBar.shadowImage = nil;
}

然后scrollView滚动时动态改变导航栏颜色

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat minAlphaOffset = - kNavConH - kStatusBarH;
    CGFloat maxAlphaOffset = 150;
    CGFloat offset = scrollView.contentOffset.y;
    CGFloat alpha = (offset - minAlphaOffset) / (maxAlphaOffset - minAlphaOffset);
    //这儿使用colorWithAlphaComponent也可以调节本视图的透明度,且子视图的透明度不受影响,用view.alpha不只本视图透明度改变了,他的所有的子视图的透明度也受影响
    self.navTopView.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:alpha];
}

demo在这儿