如何在隐藏子视图或修改子视图高度时缩小UICollectionView可复用header高度
问题根源
你当前直接为UICollectionViewFlowLayout的headerReferenceSize设置了固定高度70,即便内部子视图约束变更,外层布局也不会自动更新header的实际尺寸,这是无法实现高度同步缩小的核心原因。
解决步骤
- 替换硬写header固定高度的代码,开启自动尺寸估算
将原有代码修改为以下内容,让flowLayout自动计算header的实际高度:
if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout { // 开启header自动尺寸估算,仅需提供近似的宽度和估算高度即可 flowLayout.estimatedHeaderReferenceSize = CGSize(width: self.collectionView.frame.width, height: 60) }
- 校验headerView内部约束是否符合自动计算要求
确保headerView本身没有添加固定高度约束,整体高度完全由子视图撑满:
- 内嵌
collectionView约束:顶部距headerView顶部固定边距、左右距headerView左右边距、高度固定为指定值、底部距filtersView顶部固定边距 filtersView约束:左右距headerView左右边距、底部距headerView底部固定边距、可修改的高度约束
如果需要在filtersView隐藏时完全消除间距,可以同步将filtersView的高度约束、以及它和内嵌collectionView的间距约束、它和headerView底部的间距约束都设置为0。
- 修改高度后触发布局刷新
每次调整filtersView的高度约束后,执行以下代码触发重新布局,同步更新header尺寸:
// 示例:隐藏filtersView headerView.filtersViewHeightConstraint.constant = 0 headerView.setNeedsLayout() headerView.layoutIfNeeded() // 通知外层collectionView刷新布局,重新计算header大小 collectionView.collectionViewLayout.invalidateLayout()
- 可选:自定义header类优化尺寸计算
如果使用自定义的UICollectionReusableView子类作为header,可以重写以下方法确保尺寸计算准确:
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { let attributes = super.preferredLayoutAttributesFitting(layoutAttributes) let targetSize = CGSize(width: layoutAttributes.frame.width, height: UIView.layoutFittingCompressedSize.height) let autoHeight = systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel).height attributes.frame.size.height = autoHeight return attributes }
内容的提问来源于stack exchange,提问作者Kegham K.
相关产品推荐
相关产品推荐

