美文网首页
个人详情页效果-导航栏显示渐现隐藏

个人详情页效果-导航栏显示渐现隐藏

作者: 丹丹十个胆小鬼 | 来源:发表于2018-12-27 11:15 被阅读0次

    效果如下:

    个人详情页
    首先看到这个效果,第一反应就是使用tableview的头部控件来实现,类似如下代码:
        //返回每一组的头部视图
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
         //在这⾥里设置组的头部视图是位置和宽⾼高都是没有效果的, 它专⻔门有⼀一个⽅方法来设置头部 视图的⾼高度
         UIView *sectionHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
         sectionHeader.backgroundColor = [UIColor yellowColor]; 
         return sectionHeader;
    }
    

    分析:因为示例效果的头部视图在滚动的时候一直是在上部0的位置,而且往下滚动时,会用放大的效果,但是这在个地方,如果使用的是TablView的的头部视图,tableView的头部视图默认是跟着一起滚动的,而且手动去设置HeaderView的y值是没有效果的,所以使用头部视图是不可行的。

    方案:使用UIViewcontrller,添加tableview,上部的效果使用UIView+ImageView来实现,图片的拉升效果设置UIImageViewcontentModel属性即可实现。

    项目预览

    首先达到导航条隐藏的效果,第一反应就是设置导航条的透明度,设置导航条透明度为0,但是没有效果,还是原来的样⼦。

    因为导航条上面那一块并不直接是导航条,它是导航条里面的⼀个子控件,所以在这里设置它没有效果,因为系统会生成⼀个半透明的图片。

          self.navigationController.navigationBar.alpha = 0.0;
    

    所以在这里可以考虑给它设置一个半透明的图片,有一个模式,必须要传默认UIBarMetricsDefault模式, 图片设为nil的时候,也没有效果,那是因为系统它做了⼀层判断,它会判断如果传入的图片为空的话,它就会帮你生成一个半透明的图片,设置导航条的背景图片

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

    同时,导航条标题文字也是需要开始隐藏,随着tableview向上滚动才会显现出来:

        // 设置导航条文字
        UILabel *titleL = [[UILabel alloc] init];
        titleL.text = @"个人详情页";
        [titleL sizeToFit];
        // 设置颜色和透明度:0-0:黑色透明,1-1:白色不透明
        titleL.textColor = [UIColor colorWithWhite:0 alpha:0];
        self.navigationItem.titleView = titleL;
    

    导航条隐藏效果实现了,现在就可以开始实现滚动向上走的效果了,如何实时的获取tableview滚动的位置?监听代理,实现代理方法,根据tableview的实时滚动位置,来求出整个HeaderView的显示高度,就可以达到一边,滚动HeaderView一边向上走的效果。实现代码如下:

    // 已经在滚动了
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        // 获取scrollview的当前偏移量
        CGPoint offset = scrollView.contentOffset;
        
        //当前Y方向的偏移量-初始偏移量=Y的偏移高度
        CGFloat offsetY = offset.y - FLOriOffsetY;
        // headerView的实时高度
        CGFloat constant = FLHeaderH - offsetY;
        
        NSLog(@"scrollH:%f,%f",offsetY,offset.y);
        // 实时高度小于64时,确定为64,导航条留出显示位置
        if (constant < 64) {
            constant = 64;
            offsetY = 136;
        }
        
        self.headVHeigthConstrain.constant = constant;
        
        // 透明度
        CGFloat alpha = offsetY / (FLHeaderH - 64);
        NSLog(@"scrollH:%f,%f",offsetY,alpha);
        // 系统如果发现传入透明度为1的背景图片,会生成一张半透明的图片替换,
        // 把透明度设置成0.99可以避免这个问题
        if (alpha == 1) {
            alpha = 0.99;
        }
        
        // 根据颜色生成一张相同颜色图片,并设置透明度
        UIImage *image = [UIImage imageWithColor:[UIColor colorWithWhite:1 alpha:alpha]];
        [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
        
        // 设置titleView文字显示
        UILabel *titleL = (UILabel *)self.navigationItem.titleView;
        titleL.textColor = [UIColor colorWithWhite:0 alpha:alpha];
    }
    

    如果你得到的效果如下:

    效果1
    是因为图片显示效果超出了控件的范围,只需要把超出的部分裁剪掉即可,在SB中勾选图片的clip to Bounds属性:
    clip to Bounds属性

    这里还是用到了UIImage的一个分类,根据颜色自动生成一张1*1图片:

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

    完整代码如下:

    #import "FLPersionDetailVC.h"
    #import "UIImage+Image.h"
    
    //头部View的⾼高度
    #define FLHeaderH 200
    //悬浮条的⾼高度
    #define FLTarBarH 44
    ///原始的便宜量.
    #define FLOriOffsetY -244
    
    @interface FLPersionDetailVC () <UITableViewDataSource, UITableViewDelegate>
    @property (weak, nonatomic) IBOutlet UITableView *tableView;
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *headVHeigthConstrain;
    
    @property (weak, nonatomic) IBOutlet UIImageView *iconImageV;
    
    @end
    
    @implementation FLPersionDetailVC
    static NSString *cellID = @"cellID";
    - (void)viewDidLoad {
        [super viewDidLoad];
        // 注册cell
        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:cellID];
        
        //iOS7之后,只要是导航控制器下的所有UIScrollView顶部都会添加额外的滚动区域. 设置当前控制器不要调整ScrollView的contentInsets
        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        self.tableView.contentInset = UIEdgeInsetsMake(FLHeaderH+FLTarBarH, 0, 0, 0);
        NSLog(@"contentInset:%@", NSStringFromUIEdgeInsets(self.tableView.contentInset));
        
        /*
         设置导航条透明度为0,没有效果,还是原来的样⼦. 原因是因为导航条上面那一块并不直接是导航条,它是导航条里面的⼀个子控件. 所以在这里设置它没有效果,因为系统会生成⼀个半透明的图片.
         
          self.navigationController.navigationBar.alpha = 0.0;
          所以在这里我们可以考虑给它设置一个半透明的图片. 在这里,有一个模式,必须要传默认UIBarMetricsDefault模式. 在这里发现设为nil的时候,也没有效果,那是因为系统它做了⼀层判断,它会判断如果传入的系统图片为空的话,它就会帮你生成一个半透明的图片,设置导航条的背景图片.
         **/
        [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
        [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
        
        // 设置导航条文字
        UILabel *titleL = [[UILabel alloc] init];
        titleL.text = @"个人详情页";
        [titleL sizeToFit];
        // 设置颜色和透明度:0-0:黑色透明,1-1:白色不透明
        titleL.textColor = [UIColor colorWithWhite:0 alpha:0];
        self.navigationItem.titleView = titleL;
        
        // 个人头像圆形显示
        self.iconImageV.layer.cornerRadius = self.iconImageV.frame.size.width *0.5;
        self.iconImageV.layer.masksToBounds = YES;
    }
    
    #pragma mark UITableViewDataSource
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 100;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
        
        cell.textLabel.text = @"个人详情";
        return cell;
    }
    
    // 已经在滚动了
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        // 获取scrollview的当前偏移量
        CGPoint offset = scrollView.contentOffset;
        
        //当前Y方向的偏移量-初始偏移量=Y的偏移高度
        CGFloat offsetY = offset.y - FLOriOffsetY;
        // headerView的实时高度
        CGFloat constant = FLHeaderH - offsetY;
        
        NSLog(@"scrollH:%f,%f",offsetY,offset.y);
        // 实时高度小于64时,确定为64,导航条留出显示位置
        if (constant < 64) {
            constant = 64;
            offsetY = 136;
        }
        
        self.headVHeigthConstrain.constant = constant;
        
        // 透明度
        CGFloat alpha = offsetY / (FLHeaderH - 64);
        NSLog(@"scrollH:%f,%f",offsetY,alpha);
        // 系统如果发现传入透明度为1的背景图片,会生成一张半透明的图片替换,
        // 把透明度设置成0.99可以避免这个问题
        if (alpha == 1) {
            alpha = 0.99;
        }
        
        // 根据颜色生成一张相同颜色图片,并设置透明度
        UIImage *image = [UIImage imageWithColor:[UIColor colorWithWhite:1 alpha:alpha]];
        [self.navigationController.navigationBar setBackgroundImage:image forBarMetrics:UIBarMetricsDefault];
        
        // 设置titleView文字显示
        UILabel *titleL = (UILabel *)self.navigationItem.titleView;
        titleL.textColor = [UIColor colorWithWhite:0 alpha:alpha];
    }
    
    
    @end
    

    相关文章

      网友评论

          本文标题:个人详情页效果-导航栏显示渐现隐藏

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