基本思路
1、继承UICollectionViewFlowLayout,在prepareLayout中计算每个section的大小,并存在有sectionBgColor的decoration UICollectionViewLayoutAttributes中。
2、在布局方法layoutAttributesForElementsInRect中,显示屏幕中的attributes
UICollectionSectionColorLayout.h
@protocol UICollectionSectionColorLayout <UICollectionViewDelegateFlowLayout>
@optional
- (UIColor *)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout backgroundColorForSection:(NSInteger)section;
@end
@interface UICollectionSectionColorLayout : UICollectionViewFlowLayout
@end
UICollectionSectionColorLayout.m
#import "UICollectionSectionColorLayout.h"
#define kDecorationReuseIdentifier @"kUICollectionSectionColorIdentifier"
@interface UICollectionSectionColorLayoutAttributes : UICollectionViewLayoutAttributes
@property (nonatomic, strong) UIColor *sectionBgColor;
@end
@implementation UICollectionSectionColorLayoutAttributes
@end
@interface UICollectionSectionColorReusableView : UICollectionReusableView
@end
@implementation UICollectionSectionColorReusableView
- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes
{
[super applyLayoutAttributes:layoutAttributes];
if ([layoutAttributes isKindOfClass:[UICollectionSectionColorLayoutAttributes class]]) {
self.backgroundColor = [(UICollectionSectionColorLayoutAttributes *)layoutAttributes sectionBgColor];
}
}
@end
@interface UICollectionSectionColorLayout (){
NSMutableArray *_decorationViewAttrs;
}
@end
@implementation UICollectionSectionColorLayout
- (void)prepareLayout
{
[super prepareLayout];
NSInteger numberOfSections = self.collectionView.numberOfSections;
if (numberOfSections == 0) {
return;
}
[self registerClass:[UICollectionSectionColorReusableView class] forDecorationViewOfKind:kDecorationReuseIdentifier];
if (!_decorationViewAttrs) {
_decorationViewAttrs = [NSMutableArray array];
}
else{
[_decorationViewAttrs removeAllObjects];
}
for (int i = 0; i < numberOfSections; i++) {
NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:i];
if (numberOfItems == 0 || ![self.collectionView.delegate conformsToProtocol:@protocol(UICollectionSectionColorLayout)]) {
continue;
}
UICollectionViewLayoutAttributes *firstAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:i]];
UICollectionViewLayoutAttributes *lastAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:numberOfItems-1 inSection:i]];
CGRect sectionFrame = CGRectUnion(firstAttr.frame, lastAttr.frame);
sectionFrame.origin.x -= self.sectionInset.left;
sectionFrame.origin.y -= self.sectionInset.top;
if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
sectionFrame.size.width += self.sectionInset.left + self.sectionInset.right;
sectionFrame.size.height = self.collectionView.frame.size.height;
}
else{
sectionFrame.size.width = self.collectionView.frame.size.width;
sectionFrame.size.height += self.sectionInset.top + self.sectionInset.bottom;
}
UICollectionSectionColorLayoutAttributes *decorationAttributes =
[UICollectionSectionColorLayoutAttributes layoutAttributesForDecorationViewOfKind:kDecorationReuseIdentifier
withIndexPath:[NSIndexPath indexPathForRow:0 inSection:i]];
decorationAttributes.frame = sectionFrame;
decorationAttributes.zIndex = -1;
UIColor *sectionBgColor = nil;
if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:backgroundColorForSection:)]) {
id<UICollectionSectionColorLayout> delegate = (id<UICollectionSectionColorLayout>)self.collectionView.delegate;
sectionBgColor = [delegate collectionView:self.collectionView layout:self backgroundColorForSection:i];
}
decorationAttributes.sectionBgColor = sectionBgColor;
[_decorationViewAttrs addObject:decorationAttributes];
}
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
NSMutableArray *allAttributes = [NSMutableArray arrayWithArray:attributes];
for (UICollectionSectionColorLayoutAttributes *attr in _decorationViewAttrs) {
if (CGRectIntersectsRect(rect, attr.frame)) {
[allAttributes addObject:attr];
}
}
return allAttributes;
}
@end