对于电商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
尾部组件)
- 添加
UICollectionViewDelegateFlowLayout
代理
// add UICollectionViewDelegateFlowLayout
@interface XXXViewController()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
- 注册表头(头部视图)
- (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;
}
- 实现头部视图
//实现头部视图
-(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;
}
- 设置头部视图高度(该方法会在列表
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);
}