UICollectionView 自定义section背景

需求:

在collectionView的每个section头部加一个渐变从section头部的白色变成灰色背景色
41A5479B-16C4-4533-965F-E2086C2C9E6F.png

解决方案:

继承UICollectionViewFlowLayout写一个自定义的layout
重写init方法, 初始化layout, 注册XXXDecorationView

- (instancetype)init {
    self = [super init];
    if (self) {
        self.itemSize = [XXXItemViewCell getCellSize];
        self.sectionInset = UIEdgeInsetsMake(0,12,9,12);
        self.minimumInteritemSpacing =9;
        self.headerReferenceSize = CGSizeMake(FULL_WIDTH,47.5);
        self.footerReferenceSize = CGSizeMake(FULL_WIDTH, 0);
        self.minimumLineSpacing = 9;
        [self registerClass:[XXXDecorationView class] forDecorationViewOfKind:@"XXXDecorationView"];//注册Decoration View
    }
    return self;
}

重写准备布局方法, 构建DecorationView不同indexPath的frame

- (void)prepareLayout{
    
    [super prepareLayout];
    
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    
    NSInteger sectionCount = self.collectionView.numberOfSections;
    if (sectionCount <= 0) {
        return;
    }
    
    CGFloat y = 0; //DecorationView的y坐标
    CGFloat availableWidth = self.collectionViewContentSize.width - (self.sectionInset.left + self.sectionInset.right); //section宽
    int itemsAcross = floorf((availableWidth + self.minimumInteritemSpacing) / (self.itemSize.width + self.minimumInteritemSpacing)); //每行几个item
    
    for (int section = 0; section < sectionCount; section++)
    {
        y += self.headerReferenceSize.height;
        y += self.sectionInset.top;
        
        dictionary[[NSIndexPath indexPathForItem:0 inSection:section]] = [NSValue valueWithCGRect:CGRectMake(0, y, self.collectionViewContentSize.width, 92)];
        
        NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];
        int rows = ceilf(itemCount/(float)itemsAcross); //每个section的item行数
        for (int row = 0; row < rows; row++)
        {
            y += self.itemSize.height;
            
            if (row < rows - 1) {
                y += self.minimumLineSpacing;
            }
        }
        y += self.sectionInset.bottom;
        y += self.footerReferenceSize.height;
    }
    
    self.shelfRects = [NSDictionary dictionaryWithDictionary:dictionary];
}

重写Decoration View的布局。

- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString*)decorationViewKind atIndexPath:(NSIndexPath *)indexPath{
    id shelfRect = self.shelfRects[indexPath];
    if (!shelfRect) {
        return nil;
    }
    
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:@"XXXDecorationView" withIndexPath:indexPath];
    attributes.frame = [shelfRect CGRectValue];
    attributes.zIndex = -1;
    
    return attributes;
}

并把Decoration View的布局加入可见区域布局。

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
    //把Decoration View的布局加入可见区域布局。
    NSMutableArray *newArray = [attributes mutableCopy];
    
    [self.shelfRects enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if (CGRectIntersectsRect([obj CGRectValue], rect))
        {
            UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:@"XXXDecorationView" withIndexPath:key];
            attributes.frame = [obj CGRectValue];
            attributes.zIndex = -1;
            [newArray addObject:attributes];
        }
    }];
    
    attributes = [NSArray arrayWithArray:newArray];
    
    return attributes;
}

XXXDecorationView需继承于UICollectionReusableView。
效果图

参考链接

你可能感兴趣的:(UICollectionView 自定义section背景)