美文网首页ios底层原理iOS牛叉的demo
KVO 设置 navigationBar 渐变透明效果

KVO 设置 navigationBar 渐变透明效果

作者: 小冰山口 | 来源:发表于2016-10-23 00:48 被阅读789次

    今天感冒了, 太特么难受了, 写个小 demo 吧

    不多说, 先看效果
    navigationBar 渐变透明效果
    思路其实很简单,监听 tableView 的滚动范围, 即 contentOffset 的 y 值,
    • 当 y 值 = 0时, navigationBar 先隐藏,
    • 当 y 刚刚大于0时, navigationBar 出现
    • 透明度其实就是 y 值和轮播图高度的比值,这比值是会随之 y值得变动而变动的, 那么我们就可以用这个来设置透明度,
    需要注意的点是:
    • 要去掉 navigationBar 的底部阴影,这样才不至于出现一条线,影响用户体验
    • 当tableView 拖到轮播图下方时, navigationBar 要保持不透明颜色
    • 系统设置 navigationBar 时,默认的是半透明状态, 很不爽,所以需要生成一张纯色图,来动态地设置 navigationBar 的背景图

    那我们来开始一步步做吧

    1. 首先,设置观察者
    #pragma mark *** 视图的生命周期 ***
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self setupUI];
        
         /* tableViewController 观察 tableView 的 contentOffset */
        [self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    }
    
    2. 当观察者的观察对象的属性一发生变化时, 就调用这个方法
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
    {
        if ([object isEqual:self.tableView] && [keyPath isEqualToString:@"contentOffset"]) {
            [self refreshNavigationBar];
        }
    }
    
    3.那么刷新 navigationBar-(void)refreshNavigationBar是个什么东西呢?
    - (void)refreshNavigationBar
    {
        CGPoint offset = self.tableView.contentOffset;
        
         /* 当 offset.y 值小于0时,状态栏隐藏, 其余时候显示 */
        self.navigationController.navigationBarHidden = (offset.y < 0);
        
         /* 在这个页面中, 我的轮播图的宽高比是180:300 */
         /* 那么我先算出轮播图的高度 */
        CGFloat cycleScrollViewHeight = kScreenWidth * 180 / 300;
        
         /* 用 offset 值比上轮播图的高度,那么,当轮播滚动范围的 y 值等于轮播图的高度时, navigationBar 就完全不透明了 */
        CGFloat alpha = MIN(1, fabs(offset.y / cycleScrollViewHeight));
        
         /* 设置 透明度为 NO 来消除 alpha 为1时的系统化透明 */
        
        BOOL translucent = !(int)alpha; /* 也就是说,当tableView 越往下拖, alpha 值为1,navigationBar 的透明度就始终保持不透明 */
        [self.navigationController.navigationBar setTranslucent:translucent];
        
         /* 设置实时的颜色 */
        UIColor *realTimeColor = [UIColor colorWithRed:0.14 green:0.79 blue:0.67 alpha:alpha];
         /* 用实时的颜色生成一张纯色的图片 */
        UIImage *image = [self navigationBarImageWithColor:realTimeColor];
        
        [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
         /* 消除阴影 */
        [self.navigationController.navigationBar setShadowImage:[UIImage new]];
        
    }
    
    

    第3步才是核心代码, 很重要,

    4.这里面还有一个重要的方法是生成一张纯色图,生成纯色图, 我们需要计算出纯色图的大小, 纯色图的大小实际上就是 navigationBar 的大小和状态栏(statusBar 的大小)
    - (UIImage *)navigationBarImageWithColor:(UIColor *)color
    {
        CGSize navigationBarSize = self.navigationController.navigationBar.frame.size;
        CGSize statusBarSize = [[UIApplication sharedApplication]statusBarFrame].size;
        
        return [UIImage yf_imageWithPureColor:color size:CGSizeMake(navigationBarSize.width, navigationBarSize.height + statusBarSize.height)];
    }
    
    5.实际上真正生成纯色图的是这个方法:yf_imageWithPureColor:color size:

    在这里,我们创造一个 UIImage 的分类,专门生成纯色图.这样,我们在项目的其他任何地方需要根据颜色和大小生成纯色图的时候,都可以调用这个方法

    创建一个生成纯色图的分类

    分类方法的实现如下:

    + (UIImage *)yf_imageWithPureColor:(UIColor *)color size:(CGSize)size
    {
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);
        [color set];
        UIRectFill(CGRectMake(0, 0, size.width, size.height));
        UIImage *renderImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        return renderImage;
    }
    
    以上, 就是完成这个功能的全部步骤.

    相关文章

      网友评论

      本文标题:KVO 设置 navigationBar 渐变透明效果

      本文链接:https://www.haomeiwen.com/subject/eaghuttx.html