How to change background color of a whole section in UICollectionView?

后端 未结 10 926
暗喜
暗喜 2020-12-13 18:21

In UICollectionView, I want to give the whole section a uniform background color, instead of for a single cell or for the whole collection view.

I don\'t see any de

相关标签:
10条回答
  • 2020-12-13 18:52

    I went off of this repo here https://github.com/SebastienMichoy/CollectionViewsDemo/tree/master/CollectionViewsDemo/Sources/Collections%20Views

    Swift 3

    subclass uicollectionreusableview

    class SectionView: UICollectionReusableView {
       static let kind = "sectionView"
    }
    

    subclass uicollectionViewFlowLayout

    class CustomFlowLayout: UICollectionViewFlowLayout {
    
    // MARK: Properties
    
    var decorationAttributes: [IndexPath: UICollectionViewLayoutAttributes]
    var sectionsWidthOrHeight: [IndexPath: CGFloat]
    
    
    // MARK: Initialization
    
    override init() {
        self.decorationAttributes = [:]
        self.sectionsWidthOrHeight = [:]
    
        super.init()
    }
    
    required init?(coder aDecoder: NSCoder) {
        self.decorationAttributes = [:]
        self.sectionsWidthOrHeight = [:]
    
        super.init(coder: aDecoder)
    }
    
    // MARK: Providing Layout Attributes
    
    override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        return self.decorationAttributes[indexPath]
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var attributes = super.layoutAttributesForElements(in: rect)
        let numberOfSections = self.collectionView!.numberOfSections
        var xOrYOffset = 0 as CGFloat
    
        for sectionNumber in 0 ..< numberOfSections {
            let indexPath = IndexPath(row: 0, section: sectionNumber)
            let numberOfItems = self.collectionView?.numberOfItems(inSection: sectionNumber)
            let sectionWidthOrHeight = numberOfItems == 0 ? UIScreen.main.bounds.height : collectionViewContentSize.height//self.sectionsWidthOrHeight[indexPath]!
            let decorationAttribute = UICollectionViewLayoutAttributes(forDecorationViewOfKind: SectionView.kind, with: indexPath)
            decorationAttribute.zIndex = -1
    
            if self.scrollDirection == .vertical {
                decorationAttribute.frame = CGRect(x: 0, y: xOrYOffset, width: self.collectionViewContentSize.width, height: sectionWidthOrHeight)
            } else {
                decorationAttribute.frame = CGRect(x: xOrYOffset, y: 0, width: sectionWidthOrHeight, height: self.collectionViewContentSize.height)
            }
    
            xOrYOffset += sectionWidthOrHeight
    
            attributes?.append(decorationAttribute)
            self.decorationAttributes[indexPath] = decorationAttribute
        }
    
        return attributes
    }
    }
    

    implement this

    CollectionView delegate function

    func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath) {
    
        Log.printLog(identifier: elementKind, message: indexPath)
        if elementKind == UICollectionElementKindSectionHeader, let view = view as? ProfileViewHeaderView {
    
            view.backgroundColor = UIColor(red: (102 / 255.0), green: (169 / 255.0), blue: (251 / 255.0), alpha: 1)
        } else if elementKind == SectionView.kind {
            let evenSectionColor = UIColor.black
            let oddSectionColor = UIColor.red
    
            view.backgroundColor = (indexPath.section % 2 == 0) ? evenSectionColor : oddSectionColor
        }
    }
    

    This is important

    let layout = CustomFlowLayout()
    layout.register(SectionView.self, forDecorationViewOfKind: SectionView.kind)
    

    register the UICollectionReusableView with layout not collectionView.

    one more thing. I messed around with the height in layoutAttributesForElements. you should change it for your own project.

    0 讨论(0)
  • 2020-12-13 18:56

    I haven't tried this out yet, but it looks to me that you need to use decoration views if you want a background behind your cells (like the shelf in the Books app). I think you should be able to have different views for each section, and set them up using the delegate method layoutAttributesForDecorationViewOfKind:atIndexPath:.

    0 讨论(0)
  • 2020-12-13 18:57

    refer to:
    strawberrycode: Use DecorationView as background
    devxoul: Use SupplementaryElement as background
    airbnb: Use SupplementaryElement as background

    I need to compatible with IGListKit, so I use decorationView as background. The layout is subclass from UICollectionViewFlowLayout for common use case. My implementation:

    0 讨论(0)
  • 2020-12-13 19:00

    The idea is to override UICollectionViewLayoutAttributes to add a color attribute. And then override UICollectionReusableView apply the color to the view background.

    https://github.com/strawberrycode/SCSectionBackground

    0 讨论(0)
提交回复
热议问题