美文网首页A知识点2iOS实用工具
iOS之导航栏的渐变隐藏及显示

iOS之导航栏的渐变隐藏及显示

作者: 请输入账号名 | 来源:发表于2017-05-21 23:55 被阅读2120次

    在项目中往往有的时候需要导航栏的状态是变化的,有的时候需要隐藏,为的是显示更多的页面,有的时候需要显示出来,给用户以提示,所以就需要隐藏和显示导航栏。正如下面的示意图所示:


    示意图

    分析

    本个项目中,展示的是一个导航控制器,其中导航控制器中有个UIViewController或者是UITableviewController为根控制器的这么一个结构。

    实现

    因此在storyboard中我们将之前控制器删除,然后拖一个导航控制器出来,然后试着先绑定一个UITableviewController为根控制器。

    导航栏的设置

    为了让我们的header view所展示的位置是在左上角的圆点位置,我们需要把自动偏移设置关掉。

        self.automaticallyAdjustsScrollViewInsets = NO;
    

    下面就需要隐藏导航栏操作了,我们都知道导航栏有一个隐藏的属性,下面试试

        self.navigationController.navigationBar.hidden = YES;
    

    这种方法虽然能够让导航栏消失隐藏掉,但是如果我们要进行滚动tableview的时候,就不能让导航栏渐变的显示出来,所以这种方法不能满足要求。
    这种方法行不通那么用透明度的方案来试试:

        self.navigationController.navigationBar.alpha = 0;
    

    截图如下:


    导航栏没有消失掉

    因此上面的方案不能实现功能。
    可以使用设置导航栏背景图片进行设置,这样就可以设置导航栏的背景有个透明度的变化。

        [self.navigationController.navigationBar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
    

    当传入的图片为nil的时候,会自动的创建一个半透明的图片作为导航栏的背景。所以这种方案是可行的,但是导航栏下面的那一根线我们是希望不显示的:

        [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
    

    这样一来,导航栏的那根线就取消掉了。
    以上导航栏的基本实现方案已经确定了,但是下面的列表的显示还有些疑问,到底是用的tableview显示,利用tableview的headerView;还是用UIViewController进行展示头部的控件,下面的部分就用tableview进行展示。

    UITableviewController 方案

    我们先试着作出示意图的效果,一个tableview上放置一个headerView。

        UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 200)];
        header.backgroundColor = [UIColor redColor];
        self.tableView.tableHeaderView = header;
    

    运行下,看效果:

    tableview header方案

    看示意图,我们可以看到整个tableview都在移动,而不是我们效果图那种的样式,在往下滚动的时候,头部的控件是不会网下移动的,但是利用tableview的headerView进行布局的方案是不成功的。

    UIViewController 方案

    我们首先在view上放置一个tableview和UIView(放置头部的那些图片)。

    页面的层级

    以上都是在storyboard中操作的。


    UIViewController方案添加header

    以上的效果图中可以看到头部的headerView没有类似于tableview的headerView那种滚动的时候出现下移的情况。所以这种方式是可行的。
    但是我们还需要设置tableview的偏移量,因为图片的显示,遮挡住了我们的列表,所以需要设置一个偏移量:

        self.tableView.contentInset = UIEdgeInsetsMake(244, 0, 0, 0);
    

    导航栏的一些细节处理

    导航栏的文字,在刚开始出现的时候是需要隐藏掉的,

        //设置标题
        UILabel *title = [[UILabel alloc] init];
        title.text = @"个人主页";
        [title sizeToFit];
        // 开始的时候看不见,所以alpha值为0
        title.textColor = [UIColor colorWithWhite:0 alpha:0];
        self.navigationItem.titleView = title;
    

    虽然我们已经把文字隐藏掉了,但是已进入到控制器,我们还是能看到导航栏,所以我们需要在进入到控制器的时候隐藏掉,就在storyboard中进行设置就可以了,选中控制器:


    隐藏导航栏

    把top Bar的设置改为None就可以了。

    实现滚动隐藏或显示导航栏

    我们知道tableview是继承自scrollView的,所以有个-scrollViewDidScroll:方法中可以拿到tableview的滚动。而且当调用contentInset会自动调用-scrollViewDidScroll:
    我们可以这个方法中监听到scrollView的偏移量:

    #pragma mark - scrollview
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        NSLog(@"%f", scrollView.contentOffset.y); //  原始偏移的位置是-244
    }
    

    所以导航栏的一些控制操作就在这个方法中进行实现。
    我们需要注意到的是,当整个页面上移到一定的位置的时候,就不在上移了,因为需要留够64的位置给导航栏进行显示。也就是说这个显示图片这部分上移到一定的位置就不在移动了。
    我们需要改变这个控件的高度,那么就需要修改这个控件高度的约束,所以就需要拖个约束到控制器中。

    // 头部展示高度约束
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageHeight;
    

    计算头部的高度:

        CGFloat offset = scrollView.contentOffset.y - oriOfftY;
        CGFloat imgH = oriHeight - offset;
        if (imgH < 64) {
            // 当上移到距离顶部小于64的时候,就不在移动了。
            imgH = 64;
        }
        self.imageHeight.constant = imgH;
    
    上移、下移
    到此我们就需要处理透明度渐变的问题了。

    由效果图可以知道,整个页面上移到一定的距离,就会完全显示出导航栏,下移一定的距离,导航栏就会消失掉。

        //透明度
        //找最大值/
        CGFloat alpha = offset * 1 / 136.0;   // (200 - 64) / 136.0f
        if (alpha >= 1) {
            // 透明度最大值
            alpha = 0.99;
        }
    

    设置文字:

        //拿到标题 标题文字的随着移动高度的变化而变化
        UILabel *titleL = (UILabel *)self.navigationItem.titleView;
        titleL.textColor = [UIColor colorWithWhite:0 alpha:alpha];
    

    最后一步就是修改导航栏的背景的渐变效果:

        //把颜色生成图片
        UIColor *alphaColor = [UIColor colorWithWhite:1 alpha:alpha];
        //把颜色生成图片
        UIImage *alphaImage = [UIImage imageWithColor:alphaColor];
        //修改导航条背景图片
        [self.navigationController.navigationBar setBackgroundImage:alphaImage forBarMetrics:UIBarMetricsDefault];
    

    -imageWithColor :这个方法是UIImage的一个分类中的方法,专门就是把颜色转换成图片的方法:

    // 颜色转为图片
    + (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;
    }
    

    以上基本完成了想要的效果图的功能了。
    代码传送门,如果有帮助你的话,GitHub上给个赞呗!

    相关文章

      网友评论

        本文标题:iOS之导航栏的渐变隐藏及显示

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