如何实现UICollectionView头部单元格顶部固定效果?
让UICollectionView头部单元格固定在顶部的实现方案
嘿,看你在用DCHoverFlowLayout来做CollectionView的布局,想要让头部单元格固定在顶部不随滚动走是吧?刚好这个需求可以通过自定义布局来搞定,给你两种可行的方案,适配你的情况:
方案一:基于你当前的DCHoverFlowLayout实现
首先先检查下你用的这个自定义布局有没有内置悬浮头部的开关——很多这类开源布局都会提供类似stickyHeadersEnabled的属性,如果有的话,直接一行代码就能搞定:
layout.stickyHeadersEnabled = YES;
如果这个布局没自带这个功能,那咱们就自己给它加逻辑:
- 第一步,重写
layoutAttributesForElementsInRect:方法,在里面调整头部视图的位置,让它滚动时固定在顶部:- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { // 先获取父类计算好的布局属性 NSArray *originalAttrs = [super layoutAttributesForElementsInRect:rect]; NSMutableArray *adjustedAttrs = [originalAttrs mutableCopy]; // 获取当前CollectionView的滚动偏移量 CGFloat currentOffsetY = self.collectionView.contentOffset.y; // 获取第0组头部视图的布局属性(如果你的头部在其他组,修改section值即可) UICollectionViewLayoutAttributes *headerAttr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]; if (headerAttr) { // 计算头部可以停留的最大Y值,避免滚动到最底部时头部被顶出屏幕 CGFloat maxHeaderY = [self collectionViewContentSize].height - headerAttr.size.height - self.collectionView.contentInset.bottom; // 最终的Y值:不能小于当前滚动偏移量(固定在顶部),也不能超过最大Y值 CGFloat targetY = MAX(currentOffsetY, MIN(maxHeaderY, headerAttr.frame.origin.y)); // 更新头部的frame headerAttr.frame = CGRectMake(headerAttr.frame.origin.x, targetY, headerAttr.frame.size.width, headerAttr.frame.size.height); // 设置zIndex让头部在最上层,不会被其他cell遮挡 headerAttr.zIndex = 1000; // 替换原有的布局属性 NSInteger index = [originalAttrs indexOfObject:headerAttr]; if (index != NSNotFound) { [adjustedAttrs replaceObjectAtIndex:index withObject:headerAttr]; } } return adjustedAttrs; } - 第二步,重写
shouldInvalidateLayoutForBoundsChange:方法,返回YES,这样每次滚动时都会重新计算布局:- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds { return YES; }
方案二:如果切换到系统UICollectionViewFlowLayout的实现
要是之后你换成系统自带的FlowLayout,同样可以用类似的思路实现悬浮头部——本质都是通过重写布局类的方法,动态调整头部视图的位置,核心逻辑和上面一致,只是父类换成UICollectionViewFlowLayout就行。
小提醒
- 确保你的头部视图是通过
UICollectionElementKindSectionHeader类型注册的,而不是普通的cell,这样布局才能正确识别它是头部补充视图。 - 记得设置头部的
zIndex,不然滚动时可能会被其他单元格挡住哦。
内容的提问来源于stack exchange,提问作者Test 87
相关产品推荐
相关产品推荐

