问题描述
我有一个带有一些自定义逻辑的大 UIcollectionView
,在它的标题中我有另一个 UICollectionView
,滚动方向设置为水平。除此之外,我在该标题视图中还有其他标签。我像这样得到标题的动态高度:
func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,referenceSizeforHeaderInSection section: Int) -> CGSize {
let indexPath = IndexPath(row: 0,section: section)
let headerView = self.collectionView(collectionView,viewForSupplementaryElementOfKind: UICollectionView.elementKindSectionHeader,at: indexPath)
let desiredWidth = collectionView.frame.width > 0 ? collectionView.frame.width : UIScreen.main.bounds.width
return headerView.systemLayoutSizefitting(CGSize(width: desiredWidth,height: UIView.layoutFittingExpandedSize.height),withHorizontalFittingPriority: .required,// Width is fixed
verticalFittingPriority: .fittingSizeLevel) // Height can be as large as needed
}
高度计算正确,但是如果我滚动水平 collectionView 然后从代码中的某个地方调用 reloadData,它的滚动位置将被重置。
我知道这是由于 let headerView = self.collectionView(collectionView,at: indexPath)
这一行而发生的,但是有没有办法让动态标题高度和滚动不被重置?
解决方法
这个问题的解决方案是在出队时保留一个headerView的实例,然后在计算header的高度时重新使用它。
if let headerView = self.headerView {
return headerView.systemLayoutSizeFitting(
CGSize(width: desiredWidth,height: UIView.layoutFittingExpandedSize.height),withHorizontalFittingPriority: .required,// Width is fixed
verticalFittingPriority: .fittingSizeLevel) // Height can be as large as needed
}
return CGSize(width: desiredWidth,height: 1)