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 delegate method to do that, any suggestions?
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 delegate method to do that, any suggestions?
This is a great tutorial for changing UICollectionView section color:
http://www.ericjchapman.com/jekyll/update/ios/2014/11/10/ios-changing-section-background-color-in-UICollectionView.html
Basically, we will have to subclass UICollectionViewLayoutAttributes
, UICollectionReusableView
and UICollectionViewLayout
in order to create a instance UICollectionReusableView as section's background view.
This is his result:
Please follow the link for more details explanation.
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:
.
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
In collection view every section can have a supplementary views, so put supplementary views for each section then set background color to supplementary views instead of section cells. I hope it will help.
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.
I have changed the background color of each section in a very simple manner in the following method: But I was not sure whether it is the right thing to do. But it did work.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
FamilyCalendarCellItemCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"calendarItem" forIndexPath:indexPath];
Event *event;
_headerView = [collectionView dequeueReusableSupplementaryViewOfKind:
UICollectionElementKindSectionHeader withReuseIdentifier:@"EventHeader" forIndexPath:indexPath]; //headerView is declared as property of Collection Reusable View class
if(indexPath.section==0) {
cell.backgroundColor=[UIColor orangeColor];
}
else if(indexPath.section==1) {
cell.backgroundColor=[UIColor yellowColor];
}
return cell;
}