IOS—UICollectionView和UITableView表头实现方式

3,453 阅读2分钟

对于电商App,经常存在如下图所示的需求——列表头部展示一个轮播广告位,并可以跟随下边的列表一起滚动。

一种实现方式是在列表外层再包裹一层 scrollView,顶部轮播广告位和列表同级放置。但这会增加视图嵌套层级,代码冗余。

另外一种实现方式是为列表添加表头,下面进行介绍。

tableView实现表头

对于 UITableView 实现表头很简单,对列表的 tableHeaderView 属性设置即可,如下所示

 self.tableView.tableHeaderView = self.topHeaderView;

collectionView实现表头

UICollectionView 并没有类似的 tableHeaderView 属性,若要实现表头,大体可分为2种方式

列表内边距

使用列表内边距,将表头在列表内边距位置处展示

// 设定列表头部内边距为顶部视图高度
 _collectionView.contentInset = UIEdgeInsetsMake(self.topHeaderViewHeightValue, 0, 0, 0);
// 将表头添加到列表中,在内边距位置展示
[_collectionView addSubView:self.topHeaderView];

UICollectionViewDelegateFlowLayout代理实现头尾

Tip: 在实际开发中,若存在复杂的回顶操作,下拉刷新,动态调整表头高度等操作,建议不要使用内边距方法实现,使用 UICollectionViewDelegateFlowLayout 代理实现更佳

借助 UICollectionViewDelegateFlowLayout,实现 UICollectionElementKindSectionHeader 表头,具体实现步骤如下(同理,也可实现 UICollectionElementKindSectionHeader 尾部组件)

  1. 添加 UICollectionViewDelegateFlowLayout 代理
// add UICollectionViewDelegateFlowLayout
@interface XXXViewController()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
  1. 注册表头(头部视图)
- (UICollectionView *) collectionView {
    if (!_collectionView) {
        UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
        // ...
        _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height-[self p_customNaviBarHeight]) collectionViewLayout:flowLayout];

        //单元格
        [_collectionView registerClass:[LPKLandPageCollectionViewCell class] forCellWithReuseIdentifier:[NSString stringWithFormat:@"%@",NSStringFromClass([LPKLandPageCollectionViewCell class])]];
        
        // 注册表头(头部视图) 
        [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"doubleNineHeader"];
        
        // 注册尾部
        [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"doubleNineHeader"];
    return _collectionView;
}
  1. 实现头部视图
//实现头部视图
-(UICollectionReusableView *) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    UICollectionReusableView *headerView =nil;
    if(kind == UICollectionElementKindSectionHeader){
        //头部视图
        headerView = [_collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"doubleNineHeader" forIndexPath:indexPath];
        headerView.backgroundColor = [UIColor clearColor];
        [headerView addSubview:self.headerTitleView];
    }
    else if(kind == UICollectionElementKindSectionFooter){ 
        //尾部视图
        // ...
    }
    return headerView;
}
  1. 设置头部视图高度(该方法会在列表 fillData 前后均调用,因此可以根据填充数据动态调整头部视图高度)
//设置头部视图高度
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
    CGFloat sectionHeaderHeight = 0.0;
    sectionHeaderHeight = self.isShowHeaderTitleInfo ? kIphone6Scale(42):kIphone6Scale(15);
    return CGSizeMake(self.view.width, sectionHeaderHeight);  
}