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

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

作者: 丹丹十个胆小鬼 | 来源:发表于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