UICollectionView with a sticky header

前端 未结 6 464
名媛妹妹
名媛妹妹 2020-12-07 10:13

I found a blog on how to make sticky headers and it works great. Only thing is I don\'t think it takes into account the sectionInserts.

This is how its intended to l

6条回答
  •  感动是毒
    2020-12-07 10:59

    You just need to create a new UICollectionViewFlowLayout with this code:

    class StickyHeaderLayout: UICollectionViewFlowLayout {
    
        override init() {
            super.init()
            self.sectionFootersPinToVisibleBounds = true
            self.sectionHeadersPinToVisibleBounds = true
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            self.sectionFootersPinToVisibleBounds = true
            self.sectionHeadersPinToVisibleBounds = true
        }
    
        override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
            guard let attributes = super.layoutAttributesForElements(in: rect) else { return nil }
    
            for attribute in attributes {
                adjustAttributesIfNeeded(attribute)
            }
            return attributes
        }
    
        override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
            guard let attributes = super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath) else { return nil }
            adjustAttributesIfNeeded(attributes)
            return attributes
        }
    
        func adjustAttributesIfNeeded(_ attributes: UICollectionViewLayoutAttributes) {
            switch attributes.representedElementKind {
            case UICollectionElementKindSectionHeader?:
                adjustHeaderAttributesIfNeeded(attributes)
            case UICollectionElementKindSectionFooter?:
                adjustFooterAttributesIfNeeded(attributes)
            default:
                break
            }
        }
    
        private func adjustHeaderAttributesIfNeeded(_ attributes: UICollectionViewLayoutAttributes) {
            guard let collectionView = collectionView else { return }
            guard attributes.indexPath.section == 0 else { return }
    
            if collectionView.contentOffset.y < 0 {
                attributes.frame.origin.y = collectionView.contentOffset.y
            }
        }
    
        private func adjustFooterAttributesIfNeeded(_ attributes: UICollectionViewLayoutAttributes) {
            guard let collectionView = collectionView else { return }
            guard attributes.indexPath.section == collectionView.numberOfSections - 1 else { return }
    
            if collectionView.contentOffset.y + collectionView.bounds.size.height > collectionView.contentSize.height {
                attributes.frame.origin.y = collectionView.contentOffset.y + collectionView.bounds.size.height - attributes.frame.size.height
            }
        }
    
    }
    

提交回复
热议问题