使用tableHeaderView的一些坑

tableView 有个属性叫tableHeaderView 用它我们可以做很多事情,现在我们最经常用的就是tableHeadView上添加自定义View 然后可做些下拉放大的图片处理,最近做项目频繁用到tableHeaderView,出现了很多问题,现总结如下:

1使用tableHeaderView的一些坑

1.tableHeaderView的官方介绍

使用tableHeaderView的一些坑_第1张图片

2.用xib 创建的自定义View 高度显示不正确



- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.tableHeaderView = self.headerView;
}

- (MineHeaderView *)headerView {
    if (!_headerView) {
        _headerView = [[NSBundle mainBundle] loadNibNamed:@"MineHeaderView" owner:nil options:nil].lastObject;
        _headerView.frame = CGRectMake(0, 0, SCREEN_WIDTH, 287);
    }
    return _headerView;
}

使用tableHeaderView的一些坑_第2张图片
加载出来发现headView竟然是一屏 虽然我设置了自定义view的高度. what ?
我们通过涂层可以发现自定义的view的高度和我们设置的不一样 why ? 初步判断 加载时 tableHeaderView的高度 是根据自定义的View高度确定的 而官方文档显示 在使用tableHeaderView前 请将该视图的高度设置为非零值 出现的问题 我这里也有疑惑 大家知道的可以在下方评论 探讨一下

解决方法 有 两种
第一种

    self.tableView.tableHeaderView = self.headerView;
    self.headerView.autoresizingMask = UIViewAutoresizingNone;

UIViewAutoresizingNone 不会随父视图的改变而改变
可参考一下 这篇文章http://www.cocoachina.com/articles/10652

第二种

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 287)];
    [view addSubview:self.headerView];
    self.tableView.tableHeaderView = view;

就是在xib View下面在加一层View (代码创建的) 这样才能保证你设置的高度是准确的 这样 自定义的view的高就固定了 在tableHeadView赋值前获取到了高度

3.用xib 创建的自定义View 会输出约束警告

使用tableHeaderView的一些坑_第3张图片
可看最后一条约束 自定义的headerView的宽度竟然为0 宽度为0 里面的view都是相对自定义view的 所以导致约束警告

解决 还可像上面一样 将其放到一个view中 设置其frame 就好了
再可 调整报警告约束的优先级

4.设置了tableView到顶部距离为0 可是展示还是会留出状态栏的高度或者 navibar的高度

使用tableHeaderView的一些坑_第4张图片
通过层级可发现 tableView到顶部的距离为0 那就是 contInset向下偏移了
所以知道怎么解决了吧

/在控制器里面viewDidLoad 写下这句代码应该就可以了

if (@available(iOS 11.0, *)){
        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        self.automaticallyAdjustsScrollViewInsets = NO;
    }

* 坐标:以屏幕左上角为原点(iOS7以前在状态栏或者导航条下)
UIScrollView(包括其子类,比如UITableView):会自动在顶部和底部预留一些空白(因为滚动经过半透明导航条或者tabbar下面,需要能隐约看到的效果),是否预留空白可以由UIViewController的
automaticallyAdjustsScrollViewInsets的这个属性控制(默认YES,表示预留空白)。
上面这些只要你用iOS开发,就能发现。

一个控制器中,出现UIScrollView(包括其子类),必须是第一个添加到控制器的视图上才会预留空白,这里的第一个是相对于所有的子视图,不仅仅是其他UIScrollView(包括其子类)。
 
那么我遇到的问题如何解决呢,还是这个属性automaticallyAdjustsScrollViewInsets,仔细看它的文档说明,它说了,如果一个控制器中出现两个以上的UIScrollView(包括其子类),这个属性需要设置为NO.即不会预留空白,那么这个控制器中所有的UIScrollView(包括其子类)都需要重新设置坐标

也可以直接设置contentInset 

2 使用tableHeaderView的场景

1.tableView下拉到一定程度不允许下拉

正常的tableView下拉 会漏出底部白色的view 产品经常会在顶部做一些处理 所以我们一般用tableHeadView处理 现在也是xib创建的自定义view 里面有一个imageView 放在tableHeaderView上 下拉图片向下拉伸 拉到90 不可再往下拖拽

首先下拉要漏出的是图片 所以可让图片超出屏幕90 这样下拉就是图片啦 是不是很简单

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGPoint point = scrollView.contentOffset;
    CGFloat offsetBaseLine = -90;
    if(point.y < offsetBaseLine) {
        scrollView.contentOffset = CGPointMake(0, offsetBaseLine);
    }
}

2.tableView下拉放大图片的处理

核心就是这句代码!
UIViewContentModeScaleAspectFill高度改变,宽度也会改变,不设置那将只会被纵向拉伸, 设置imageView的高度为屏幕的高

代码如下

self.zoomImageView.contentMode = UIViewContentModeScaleAspectFill;
self.zoomImageView.clipsToBounds = NO;  //防止手势返回图片过多
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGPoint point = scrollView.contentOffset;
    if (point.y <= 0) {
        self.headerView.frame = CGRectMake(0, point.y, self.view.frame.size.width, 260 - point.y);
    }
}

3.自定义headerView在顶部固定 tableView下拉起始位置在自定义headView的下面 上滑要求自定义headerView随着tableView一起向上滚动

这个就是需要设置tableView的ContentInset为自定义headerView的高是关键 让其自定义的headerView在其tableView顶部的ContentInset这段距离的空白处 HeaderView盖住了tableView的顶部 跟随tableView 一起滚动 重新设置自定义headerView的frame就可以了

代码如下

- (void)viewDidLoad {
    [super viewDidLoad];
    
      self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) style:UITableViewStylePlain];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.view addSubview:self.tableView];
     self.tableView.contentInset = UIEdgeInsetsMake(260, 0, 0, 0);
    [self.view addSubview:self.headerView];
}


- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat offSetY = scrollView.contentOffset.y + self.tableView.contentInset.top;
    
    if (offSetY >= 0) {
        self.headerView.frame = CGRectMake(0, -offSetY, self.view.frame.size.width, 260);
        
    } else {
        self.headerView.frame = CGRectMake(0, 0, self.view.frame.size.width, 260);
    }
}

最近遇到的问题 就是这些了 欢迎大家发言探讨哦~ 另转载请注明出处!

你可能感兴趣的:(个人代码)