使用tableHeaderView的一些坑

本文总结了在iOS开发中使用tableHeaderView时遇到的一些问题,包括高度显示不正确、约束警告、与状态栏或navigationBar间距的处理,以及在不同场景下的应用,如下拉放大图片和自定义headerView的滚动效果。通过代码和解决方案,帮助开发者理解和解决这些问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

1使用tableHeaderView的一些坑

1.tableHeaderView的官方介绍

在这里插入图片描述

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;
}

在这里插入图片描述
加载出来发现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 会输出约束警告

在这里插入图片描述
可看最后一条约束 自定义的headerView的宽度竟然为0 宽度为0 里面的view都是相对自定义view的 所以导致约束警告

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

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

在这里插入图片描述
通过层级可发现 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);
    }
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值