这是我在StackOverflow
上的第一篇文章,我是Swift的新手。
我使用UICollectionView
实现了类似于Android的CollapsingToolbarLayout,并使用自定义CollectionViewFlowLayout动态更改了标头的高度。
但是当我向上滚动时,标题消失了,并且发现它消失了一定高度。
有人有任何想法或遇到过相同的问题吗?
我尝试将headerReferenceSize
或sectionHeaderPinToVisibleBound
添加到我的自定义布局中,但是前者失败了,后者修复了页眉的高度。
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let layoutAttributes = super.layoutAttributesForElements(in: rect)
layoutAttributes?.forEach({ (attribute) in
if attribute.representedElementKind == UICollectionView.elementKindSectionHeader{
guard let collectionView = collectionView else {return}
let contentOffsetY = collectionView.contentOffset.y
let width = collectionView.frame.width
let height = attribute.frame.height - contentOffsetY
let titleHeight = UIScreen.main.bounds.height/10
let testHeight = attribute.frame.height - titleHeight
if contentOffsetY > testHeight {
attribute.frame = CGRect(x: 0, y: contentOffsetY, width: width, height: titleHeight)
headerReferenceSize = CGSize(width: width, height: titleHeight)
} else {
attribute.frame = CGRect(x: 0, y: contentOffsetY, width: width, height: height)
}
}
})
return layoutAttributes
}
上面是问题演示的链接,很抱歉,我不知道如何将视频粘贴到StackOverflow
答案 0 :(得分:0)
发生这种情况的原因是,向上滚动一定时间后,使用不同的CGRect调用layoutAttributesForElements。
我有相同的效果,可以通过在viewDidLoad()中设置sectionHeadersPinToVisibleBounds = true来消除它
if let layout = collectionViewLayout as? UICollectionViewFlowLayout {
layout.sectionInset = .init(top: kPadding, left: kPadding, bottom: kPadding, right: kPadding)
layout.minimumLineSpacing = 10
layout.headerReferenceSize = .init(width: self.view.frame.width, height: ProfileViewHeader.kHeight)
layout.sectionHeadersPinToVisibleBounds = true
}
但是将不再为滚动视图的每一步调用layoutAttributesForElements(in :)。如果只需要设置标题的布局,则最好像这样使用layoutAttributesForElements(ofKind:at:)
override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
if let attributes = super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath) {
if attributes.representedElementKind == UICollectionView.elementKindSectionHeader {
guard let collectionView = collectionView else { return attributes }
let contentOffsetY = collectionView.contentOffset.y
let width = collectionView.frame.width
let newHeight = attributes.frame.height - contentOffsetY
let height = newHeight > 64 ? newHeight: 64
attributes.frame = CGRect(x: 0, y: contentOffsetY, width: width, height: height)
if let headerView = collectionView.supplementaryView(forElementKind: UICollectionView.elementKindSectionHeader, at: attributes.indexPath) as? ProfileViewHeader {
headerView.blur(alpha: (contentOffsetY > 0) ? 0.0 : abs(contentOffsetY * 2) / 100)
}
}
return attributes
}
return nil
}