91 lines
3.8 KiB
Objective-C
91 lines
3.8 KiB
Objective-C
//
|
|
// KBSvipFlowLayout.m
|
|
// keyBoard
|
|
//
|
|
// SVIP 页面自定义布局,支持 Section 背景装饰视图
|
|
//
|
|
|
|
#import "KBSvipFlowLayout.h"
|
|
#import "KBSvipBenefitBgView.h"
|
|
|
|
static NSString * const kKBSvipDecorationViewKind = @"KBSvipBenefitBgDecoration";
|
|
|
|
@interface KBSvipFlowLayout ()
|
|
@property (nonatomic, strong) NSMutableArray<UICollectionViewLayoutAttributes *> *decorationAttributes;
|
|
@end
|
|
|
|
@implementation KBSvipFlowLayout
|
|
|
|
- (instancetype)init {
|
|
if (self = [super init]) {
|
|
_decorationSection = 1; // 默认 Section 1 需要背景
|
|
[self registerClass:[KBSvipBenefitBgView class] forDecorationViewOfKind:kKBSvipDecorationViewKind];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)prepareLayout {
|
|
[super prepareLayout];
|
|
|
|
self.decorationAttributes = [NSMutableArray array];
|
|
|
|
NSInteger numberOfSections = [self.collectionView numberOfSections];
|
|
if (self.decorationSection >= numberOfSections) { return; }
|
|
|
|
NSInteger numberOfItems = [self.collectionView numberOfItemsInSection:self.decorationSection];
|
|
if (numberOfItems == 0) { return; }
|
|
|
|
// 获取 Section Header 的布局属性
|
|
UICollectionViewLayoutAttributes *headerAttr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:self.decorationSection]];
|
|
|
|
// 获取第一个和最后一个 item 的布局属性
|
|
UICollectionViewLayoutAttributes *firstItemAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:self.decorationSection]];
|
|
UICollectionViewLayoutAttributes *lastItemAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:numberOfItems - 1 inSection:self.decorationSection]];
|
|
|
|
if (!firstItemAttr || !lastItemAttr) { return; }
|
|
|
|
// 计算背景区域
|
|
UIEdgeInsets sectionInset = self.sectionInset;
|
|
if ([self.collectionView.delegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)]) {
|
|
sectionInset = [(id<UICollectionViewDelegateFlowLayout>)self.collectionView.delegate collectionView:self.collectionView layout:self insetForSectionAtIndex:self.decorationSection];
|
|
}
|
|
|
|
CGFloat minY = CGRectGetMinY(headerAttr.frame);
|
|
CGFloat maxY = CGRectGetMaxY(lastItemAttr.frame) + 16; // 底部留 16 间距
|
|
CGFloat x = sectionInset.left;
|
|
CGFloat width = self.collectionView.bounds.size.width - sectionInset.left - sectionInset.right;
|
|
|
|
CGRect decorationFrame = CGRectMake(x, minY, width, maxY - minY);
|
|
|
|
UICollectionViewLayoutAttributes *decorationAttr = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:kKBSvipDecorationViewKind withIndexPath:[NSIndexPath indexPathForItem:0 inSection:self.decorationSection]];
|
|
decorationAttr.frame = decorationFrame;
|
|
decorationAttr.zIndex = -1; // 放在最底层
|
|
|
|
[self.decorationAttributes addObject:decorationAttr];
|
|
}
|
|
|
|
- (NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
|
|
NSMutableArray *attrs = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
|
|
|
|
for (UICollectionViewLayoutAttributes *decorationAttr in self.decorationAttributes) {
|
|
if (CGRectIntersectsRect(rect, decorationAttr.frame)) {
|
|
[attrs addObject:decorationAttr];
|
|
}
|
|
}
|
|
|
|
return attrs;
|
|
}
|
|
|
|
- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath {
|
|
if ([elementKind isEqualToString:kKBSvipDecorationViewKind]) {
|
|
for (UICollectionViewLayoutAttributes *attr in self.decorationAttributes) {
|
|
if (attr.indexPath.section == indexPath.section) {
|
|
return attr;
|
|
}
|
|
}
|
|
}
|
|
return [super layoutAttributesForDecorationViewOfKind:elementKind atIndexPath:indexPath];
|
|
}
|
|
|
|
@end
|