带约束的嵌套Collection View异常问题(Swift 4)
搞定嵌套CollectionView适配TableViewCell的问题
嘿,这个嵌套滚动禁用后的高度适配问题我之前也踩过坑,核心就是让每一层的容器都能根据内容自动计算高度,一步步来就能解决:
1. 先让纵向CollectionView自适应内容高度
既然你已经把纵向CollectionView的isScrollEnabled设为false了,那它就变成了一个“静态容器”,我们要让它的高度完全贴合内部单元格的总高度:
- 首先确保纵向CollectionView的FlowLayout设置了
estimatedItemSize = UICollectionViewFlowLayout.automaticSize,同时每个纵向单元格的AutoLayout约束要完整(上下左右都有约束,让系统能算出单元格的高度)。 - 然后监听纵向CollectionView的
contentSize变化,或者在刷新数据后手动更新它的高度约束:
// 假设你给纵向CollectionView加了一个heightConstraint的IBOutlet private func updateVerticalCVHeight() { verticalCV.layoutIfNeeded() // 强制刷新布局,确保contentSize准确 verticalCVHeightConstraint.constant = verticalCV.contentSize.height verticalCV.superview?.layoutIfNeeded() // 让父容器(横向CollectionViewCell)跟着更新 }
2. 让横向CollectionView的页面Cell自适应高度
横向CollectionView的每个Cell里装着纵向CollectionView,所以这个Cell的高度必须等于内部纵向CV的高度:
- 给横向CollectionViewCell添加高度约束,直接绑定到内部纵向CV的高度(或者在纵向CV高度更新后,手动修改横向Cell的高度约束)。
- 同样给横向CollectionView的FlowLayout设置
estimatedItemSize = .automaticSize,并且让横向Cell的preferredLayoutAttributesFitting(_:)方法正确返回自适应后的尺寸:
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes { let attributes = super.preferredLayoutAttributesFitting(layoutAttributes) layoutIfNeeded() attributes.size = systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) return attributes }
3. 最后让TableViewCell自适应整体高度
外层的TableViewCell要根据横向CollectionView的高度来调整自身高度:
- 给TableView设置
rowHeight = UITableView.automaticDimension,同时设置一个合理的estimatedRowHeight(比如estimatedRowHeight = 300),让TableView能自动计算Cell高度。 - 确保横向CollectionView在TableViewCell里的AutoLayout约束完整(上下左右都钉死),这样TableView就能根据横向CV的高度来确定Cell的高度。
关键注意事项
- 刷新数据的顺序很重要:先刷新纵向CollectionView,更新它的高度,再刷新横向CollectionView,最后调用TableView的
beginUpdates()和endUpdates()来触发高度更新。 - 所有层级的AutoLayout约束不能有歧义,每一层的容器都要有明确的约束让系统能计算尺寸。
- 如果是Objective-C项目,思路完全一致,只是语法上用
addObserver监听contentSize,或者手动计算高度即可。
举个实际刷新数据的代码片段:
func refreshAllData() { // 先更新纵向CV的数据 verticalCV.reloadData() updateVerticalCVHeight() // 再刷新横向CV horizontalCV.reloadData() horizontalCV.collectionViewLayout.invalidateLayout() // 最后让TableView更新Cell高度 tableView.beginUpdates() tableView.endUpdates() }
这样一套操作下来,不管纵向CollectionView有多少个单元格,整个嵌套结构的高度都会自动适配内容,TableViewCell也能完美贴合这个高度,再也不会出现适配问题啦~
内容的提问来源于stack exchange,提问作者Saeed Rahmatolahi
相关产品推荐
相关产品推荐

