collectionView组头悬浮效果

2019-07-06  本文已影响0人  银月流苏
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
    }
上一篇下一篇

猜你喜欢

热点阅读