UICollectionView沒有設(shè)置Section背景顏色的屬性验懊。需要自定義布局對(duì)象(UICollectionViewLayout)
Section的背景顏色屬于UICollectionView的 Decoration(裝飾)視圖 。
Decoration 視圖無法通過數(shù)據(jù)源來設(shè)置,而是由布局對(duì)象來定義和管理睦优。
無論是定義 Cell 視圖辱匿、Supplementary 視圖還是 Decoration 視圖都是通過它們的 attributes(UICollectionViewLayoutAttributes)來定義的顽分。
1.由于沒有backgroundColor屬性。需要自定義UICollectionViewLayoutAttributes
private class FLFoodCategoryCollectionViewLayoutAttributes: UICollectionViewLayoutAttributes {
var backgroundColor = UIColor.clear
}
2.Decoration視圖屬于UICollectionReusableView 的子類含友,但Decoration 視圖無法通過數(shù)據(jù)源來設(shè)置,也沒有 dequeue相關(guān)的方法校辩,所以自定義的屬性是通過 UICollectionReusableView 的 apply 方法在 UICollectionView 布局時(shí)生效窘问。
private class FLFoodCategoryCollectionReusableView: UICollectionReusableView {
private override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes)
guard let attr = layoutAttributes as? FLFoodCategoryCollectionViewLayoutAttributes else {
return
}
self.backgroundColor = attr.backgroundColor
}
}
3.添加自定義的布局對(duì)象到Decoration 視圖上
- 注冊(cè)Decoration 視圖
- 定義Decoration視圖的布局attributes
- layoutAttributesForElementsInRect返回 Decoration 視圖的布局 attributes
class FLFoodCategoryCollectionViewFlowLayout: UICollectionViewFlowLayout {
private var decorationViewAttrs: [UICollectionViewLayoutAttributes] = []
override init() {
super.init()
//注冊(cè)
self.register(FLFoodCategoryCollectionReusableView.classForCoder(), forDecorationViewOfKind: "SectionBackground")
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func prepare() {
super.prepare()
//Section個(gè)數(shù)
guard let numberOfSections = self.collectionView?.numberOfSections,
let delegate = self.collectionView?.delegate as? FLFoodCategoryCollectionViewDelegateFlowLayout
else {
return
}
self.decorationViewAttrs.removeAll()
for section in 0..<numberOfSections {
guard let numberOfItems = self.collectionView?.numberOfItems(inSection: section),
numberOfItems > 0,
let firstItem = self.layoutAttributesForItem(at: IndexPath(item: 0, section: section)),
let lastItem = self.layoutAttributesForItem(at: IndexPath(item: numberOfItems - 1, section: section)) else {
continue
}
var sectionInset = self.sectionInset
if let inset = delegate.collectionView?(self.collectionView!, layout: self, insetForSectionAt: section) {
sectionInset = inset
}
var sectionFrame = firstItem.frame.union(lastItem.frame)
sectionFrame.origin.x = 0
sectionFrame.origin.y -= sectionInset.top
if self.scrollDirection == .horizontal {
sectionFrame.size.width += sectionInset.left + sectionInset.right
sectionFrame.size.height = self.collectionView!.frame.height
} else {
sectionFrame.size.width = self.collectionView!.frame.width
sectionFrame.size.height += sectionInset.top + sectionInset.bottom
}
// 2、定義視圖屬性
let attr = FLFoodCategoryCollectionViewLayoutAttributes(forDecorationViewOfKind: "SectionBackground", with: IndexPath(item: 0, section: section))
attr.frame = sectionFrame
attr.zIndex = -1
attr.backgroundColor = delegate.collectionView(self.collectionView!, layout: self, backgroundColorForSectionAt: section)
self.decorationViewAttrs.append(attr)
}
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
var attrs = super.layoutAttributesForElements(in: rect)
attrs?.append(contentsOf: self.decorationViewAttrs.filter {
return rect.intersects($0.frame)
})
return attrs // 3宜咒、返回
}
}
4.為視圖布局增加修改顏色的屬性方法
protocol FLFoodCategoryCollectionViewDelegateFlowLayout: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, backgroundColorForSectionAt section: Int) -> UIColor
}