首页 > 解决方案 > 计算动态标题大小时,在 reloadData 上重置滚动位置

问题描述

我有一个很大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, viewForSupplementaryElementOfKind: UICollectionView.elementKindSectionHeader, at: indexPath)这条线而发生的,但是有没有办法让标题高度动态并且滚动不被重置?

标签: iosswiftuicollectionview

解决方案


这个问题的解决方案是在出队时保留一个 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)

推荐阅读