override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
//首先获取当前屏幕页面的布局信息
var superArray = super.layoutAttributesForElements(in: rect) ?? []
//通过两个for循环将s删选出已经被系统回收掉的header信息。
let nonoHeaderSections = NSMutableIndexSet.init()
for attributes in superArray {
if attributes.representedElementCategory == UICollectionView.ElementCategory.cell{
nonoHeaderSections.add(attributes.indexPath.section)
}
}
for attributes in superArray {
if attributes.representedElementKind == UICollectionView.elementKindSectionHeader {
nonoHeaderSections.remove(attributes.indexPath.section)
}
}
//确定了被回收的header信息后重复添加到布局信息的数组中
for (index, item) in nonoHeaderSections.enumerated() {
let indexPath = IndexPath.init(item: 0, section: item)
if let attributes = self.layoutAttributesForSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, at: indexPath) {
superArray.append(attributes)
}
}
//根据section中第一cell和最后一个cell的位置来确定header的位置。
for attributes in superArray {
if attributes.representedElementKind == UICollectionView.elementKindSectionHeader {
let numberOfItemsInSection = self.collectionView?.numberOfItems(inSection: attributes.indexPath.section) ?? 0
let firstItemIndexPath = IndexPath.init(item: 0, section: attributes.indexPath.section)
let lastItemIndexPath = IndexPath.init(item: max(0, numberOfItemsInSection - 1), section: attributes.indexPath.section)
var firstItemAttributes: UICollectionViewLayoutAttributes?, lastItemAttributes: UICollectionViewLayoutAttributes?
if numberOfItemsInSection > 0 {
firstItemAttributes = self.layoutAttributesForItem(at: firstItemIndexPath)
lastItemAttributes = self.layoutAttributesForItem(at: lastItemIndexPath)
}else {
firstItemAttributes = UICollectionViewLayoutAttributes.init()
let y: CGFloat = attributes.frame.maxY + self.sectionInset.top
firstItemAttributes?.frame = CGRect.init(x: 0, y: y, width: 0, height: 0)
lastItemAttributes = firstItemAttributes
}
var headerRect = attributes.frame
let currentOffset = (self.collectionView?.contentOffset.y ?? 0)
let headerY: CGFloat = (firstItemAttributes?.frame.origin.y ?? 0) - headerRect.height - self.sectionInset.top
//重点思考,在组头距离组尾很远的情况下
let finialHeaderY = max(headerY, currentOffset)
let headerMissingY = (lastItemAttributes?.frame.maxY ?? 0) + self.sectionInset.bottom - headerRect.height
//重点思考,在组头已经到达组尾,将要消失的情况下
headerRect.origin.y = min(finialHeaderY, headerMissingY)
attributes.frame = headerRect
attributes.zIndex = 7
//确定正在悬浮的header
if headerRect.minY == currentOffset || headerRect.minY == headerMissingY {
attributes.alpha = 0.8
}else {
attributes.alpha = 1
}
}
}
return superArray
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
collectionView组头悬浮效果
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 1. 如果不注册组头view 那么[tableView headerViewForSection:next1];获...
- 先上效果图 实现方式 只需要在自定义cell上加上一个view,然后把view设置边框阴影
- 引言: 瀑布流效果是商品展示效果中一个较难实现的样式, 接下来我们介绍一个支持垂直, 水平, 浮动效果的瀑布流, ...
- 实现起来的方法有点笨,但是效果还可以 大体思路: 一般实现这种效果都是写一个布局和你要置顶的布局格式一样,然后将之...