Files
keyboard/keyBoard/Class/Pay/V/KBSvipFlowLayout.m
2026-02-04 15:40:45 +08:00

138 lines
5.6 KiB
Objective-C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// KBSvipFlowLayout.m
// keyBoard
//
// SVIP 页面自定义布局,支持多个 Section 背景装饰视图
//
#import "KBSvipFlowLayout.h"
#import "KBSvipBenefitBgView.h"
static NSString * const kKBSvipOuterBgKind = @"KBSvipOuterBgDecoration"; // 外层大背景18圆角包裹全部
static NSString * const kKBSvipBenefitBgKind = @"KBSvipBenefitBgDecoration"; // 内层权益背景15圆角
#pragma mark - 外层大背景视图18圆角包裹订阅选项+权益列表)
@interface KBSvipOuterBgView : UICollectionReusableView
@end
@implementation KBSvipOuterBgView
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
self.layer.cornerRadius = 18;
self.layer.masksToBounds = YES;
}
return self;
}
@end
#pragma mark - KBSvipFlowLayout
@interface KBSvipFlowLayout ()
@property (nonatomic, strong) NSMutableArray<UICollectionViewLayoutAttributes *> *decorationAttributes;
@end
@implementation KBSvipFlowLayout
- (instancetype)init {
if (self = [super init]) {
_decorationSection = 1; // Section 1 是权益列表
[self registerClass:[KBSvipOuterBgView class] forDecorationViewOfKind:kKBSvipOuterBgKind];
[self registerClass:[KBSvipBenefitBgView class] forDecorationViewOfKind:kKBSvipBenefitBgKind];
}
return self;
}
- (void)prepareLayout {
[super prepareLayout];
self.decorationAttributes = [NSMutableArray array];
NSInteger numberOfSections = [self.collectionView numberOfSections];
if (numberOfSections < 2) { return; }
NSInteger itemCount0 = [self.collectionView numberOfItemsInSection:0];
NSInteger itemCount1 = [self.collectionView numberOfItemsInSection:1];
if (itemCount0 == 0 || itemCount1 == 0) { return; }
// 获取 Section 0 第一个 item
UICollectionViewLayoutAttributes *firstItemAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
// 获取 Section 1 Header
UICollectionViewLayoutAttributes *benefitHeaderAttr = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
// 获取 Section 1 最后一个 item
UICollectionViewLayoutAttributes *lastBenefitAttr = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForItem:itemCount1 - 1 inSection:1]];
if (!firstItemAttr || !benefitHeaderAttr || !lastBenefitAttr) { return; }
UIEdgeInsets sectionInset0 = [self insetForSection:0];
UIEdgeInsets sectionInset1 = [self insetForSection:1];
// 固定的外层背景边距(不跟随 Section inset
CGFloat outerPadding = 16;
// 1. 外层大背景18圆角固定距离屏幕左右 16
{
CGFloat minY = CGRectGetMinY(firstItemAttr.frame) - sectionInset0.top;
CGFloat maxY = CGRectGetMaxY(lastBenefitAttr.frame) + 16;
CGFloat x = outerPadding;
CGFloat width = self.collectionView.bounds.size.width - outerPadding * 2;
CGRect frame = CGRectMake(x, minY, width, maxY - minY);
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:kKBSvipOuterBgKind withIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
attr.frame = frame;
attr.zIndex = -2; // 最底层
[self.decorationAttributes addObject:attr];
}
// 2. 内层权益背景15圆角从 Section 1 Header 到 Section 1 底部,左右距离外层 8px
{
CGFloat innerPadding = 8; // 距离外层背景的边距
CGFloat minY = CGRectGetMinY(benefitHeaderAttr.frame);
CGFloat maxY = CGRectGetMaxY(lastBenefitAttr.frame) + 16;
CGFloat x = outerPadding + innerPadding;
CGFloat width = self.collectionView.bounds.size.width - (outerPadding + innerPadding) * 2;
CGRect frame = CGRectMake(x, minY, width, maxY - minY);
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:kKBSvipBenefitBgKind withIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]];
attr.frame = frame;
attr.zIndex = -1; // 在外层背景之上
[self.decorationAttributes addObject:attr];
}
}
- (UIEdgeInsets)insetForSection:(NSInteger)section {
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:section];
}
return sectionInset;
}
- (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 {
for (UICollectionViewLayoutAttributes *attr in self.decorationAttributes) {
if ([attr.representedElementKind isEqualToString:elementKind] && attr.indexPath.section == indexPath.section) {
return attr;
}
}
return [super layoutAttributesForDecorationViewOfKind:elementKind atIndexPath:indexPath];
}
@end