This commit is contained in:
2026-02-04 15:40:45 +08:00
parent 7c7e2477cb
commit c1b50b407d
13 changed files with 146 additions and 32 deletions

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "pay_leftline_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "pay_leftline_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "pay_rightline_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "pay_rightline_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 B

View File

@@ -33,11 +33,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy, nullable) NSString *currency; @property (nonatomic, copy, nullable) NSString *currency;
/// 文案描述 /// 文案描述
@property (nonatomic, copy, nullable) NSString *productDescription; @property (nonatomic, copy, nullable) NSString *productDescription;
/// 等级1=VIP, 2=SVIP
@property (nonatomic, assign) NSInteger level;
/// 展示金币(自动拼接单位) /// 展示金币(自动拼接单位)
- (NSString *)coinsDisplayText; - (NSString *)coinsDisplayText;
/// 展示价格,保留两位小数 /// 展示价格,保留两位小数
- (NSString *)priceDisplayText; - (NSString *)priceDisplayText;
/// 展示价格数字(不含货币符号)
- (NSString *)priceNumberText;
@end @end

View File

@@ -35,4 +35,8 @@
return [NSString stringWithFormat:@"%.2f", priceValue]; return [NSString stringWithFormat:@"%.2f", priceValue];
} }
- (NSString *)priceNumberText {
return [NSString stringWithFormat:@"%.2f", self.price];
}
@end @end

View File

@@ -27,7 +27,7 @@
[self.coverView mas_makeConstraints:^(MASConstraintMaker *make) { [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.contentView).inset(8); make.left.right.equalTo(self.contentView).inset(16);
make.centerY.equalTo(self.contentView); make.centerY.equalTo(self.contentView);
make.height.mas_equalTo(46); make.height.mas_equalTo(46);
}]; }];

View File

@@ -70,12 +70,15 @@ static NSString * const kKBSvipBenefitBgKind = @"KBSvipBenefitBgDecoration"; //
UIEdgeInsets sectionInset0 = [self insetForSection:0]; UIEdgeInsets sectionInset0 = [self insetForSection:0];
UIEdgeInsets sectionInset1 = [self insetForSection:1]; UIEdgeInsets sectionInset1 = [self insetForSection:1];
// 1. 18 Section 0 Section 1 // Section inset
CGFloat outerPadding = 16;
// 1. 18 16
{ {
CGFloat minY = CGRectGetMinY(firstItemAttr.frame) - sectionInset0.top; CGFloat minY = CGRectGetMinY(firstItemAttr.frame) - sectionInset0.top;
CGFloat maxY = CGRectGetMaxY(lastBenefitAttr.frame) + 16; CGFloat maxY = CGRectGetMaxY(lastBenefitAttr.frame) + 16;
CGFloat x = sectionInset0.left; CGFloat x = outerPadding;
CGFloat width = self.collectionView.bounds.size.width - sectionInset0.left - sectionInset0.right; CGFloat width = self.collectionView.bounds.size.width - outerPadding * 2;
CGRect frame = CGRectMake(x, minY, width, maxY - minY); CGRect frame = CGRectMake(x, minY, width, maxY - minY);
@@ -87,10 +90,11 @@ static NSString * const kKBSvipBenefitBgKind = @"KBSvipBenefitBgDecoration"; //
// 2. 15 Section 1 Header Section 1 8px // 2. 15 Section 1 Header Section 1 8px
{ {
CGFloat innerPadding = 8; //
CGFloat minY = CGRectGetMinY(benefitHeaderAttr.frame); CGFloat minY = CGRectGetMinY(benefitHeaderAttr.frame);
CGFloat maxY = CGRectGetMaxY(lastBenefitAttr.frame) + 16; CGFloat maxY = CGRectGetMaxY(lastBenefitAttr.frame) + 16;
CGFloat x = sectionInset0.left + 8; // 8px CGFloat x = outerPadding + innerPadding;
CGFloat width = self.collectionView.bounds.size.width - sectionInset0.left - sectionInset0.right - 16; // 8px CGFloat width = self.collectionView.bounds.size.width - (outerPadding + innerPadding) * 2;
CGRect frame = CGRectMake(x, minY, width, maxY - minY); CGRect frame = CGRectMake(x, minY, width, maxY - minY);

View File

@@ -10,7 +10,9 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface KBSvipSubscribeCell : UICollectionViewCell @interface KBSvipSubscribeCell : UICollectionViewCell
/// 配置展示文案 /// 配置展示文案(带货币符号)
- (void)configTitle:(NSString *)title currency:(NSString *)currency price:(NSString *)price strike:(nullable NSString *)strike;
/// 配置展示文案(兼容旧方法)
- (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike; - (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike;
/// 同步选中态 /// 同步选中态
- (void)applySelected:(BOOL)selected animated:(BOOL)animated; - (void)applySelected:(BOOL)selected animated:(BOOL)animated;

View File

@@ -10,7 +10,9 @@
@interface KBSvipSubscribeCell () @interface KBSvipSubscribeCell ()
@property (nonatomic, strong) UIImageView *bgImageView; // @property (nonatomic, strong) UIImageView *bgImageView; //
@property (nonatomic, strong) UILabel *titleLabel; // "1 Week" / "1 Month" / "1 Year" @property (nonatomic, strong) UILabel *titleLabel; // "1 Week" / "1 Month" / "1 Year"
@property (nonatomic, strong) UILabel *priceLabel; // "$6.90" @property (nonatomic, strong) UIView *priceContainer; //
@property (nonatomic, strong) UILabel *currencyLabel; // "$"
@property (nonatomic, strong) UILabel *priceLabel; // "6.90"
@property (nonatomic, strong) UILabel *strikeLabel; // 线 @property (nonatomic, strong) UILabel *strikeLabel; // 线
@end @end
@@ -26,19 +28,38 @@
}]; }];
[self.contentView addSubview:self.titleLabel]; [self.contentView addSubview:self.titleLabel];
[self.contentView addSubview:self.priceLabel]; [self.contentView addSubview:self.priceContainer];
[self.contentView addSubview:self.strikeLabel];
//
[self.priceContainer addSubview:self.currencyLabel];
[self.priceContainer addSubview:self.priceLabel];
[self.priceContainer addSubview:self.strikeLabel];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.contentView); make.centerX.equalTo(self.contentView);
make.top.equalTo(self.contentView).offset(12); make.top.equalTo(self.contentView).offset(10);
}]; }];
[self.priceContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentView).offset(5);
make.right.equalTo(self.contentView).offset(-5);
make.bottom.equalTo(self.contentView).offset(-5);
make.height.mas_equalTo(86);
}];
//
[self.currencyLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.priceLabel.mas_left).offset(-2);
make.bottom.equalTo(self.priceLabel.mas_bottom).offset(-4); //
}];
[self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.contentView); make.centerX.equalTo(self.priceContainer).offset(6); //
make.top.equalTo(self.titleLabel.mas_bottom).offset(8); make.centerY.equalTo(self.priceContainer).offset(-8);
}]; }];
[self.strikeLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.strikeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.contentView); make.centerX.equalTo(self.priceContainer);
make.top.equalTo(self.priceLabel.mas_bottom).offset(4); make.top.equalTo(self.priceLabel.mas_bottom).offset(4);
}]; }];
} }
@@ -55,9 +76,10 @@
[self applySelected:selected animated:NO]; [self applySelected:selected animated:NO];
} }
- (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike { - (void)configTitle:(NSString *)title currency:(NSString *)currency price:(NSString *)price strike:(nullable NSString *)strike {
self.titleLabel.text = title.length ? title : @"1 Month"; self.titleLabel.text = title.length ? title : @"1 Month";
self.priceLabel.text = price.length ? price : @"$6.90"; self.currencyLabel.text = currency.length ? currency : @"$";
self.priceLabel.text = price.length ? price : @"6.90";
self.strikeLabel.hidden = (strike.length == 0); self.strikeLabel.hidden = (strike.length == 0);
if (strike.length) { if (strike.length) {
NSDictionary *attr = @{ NSDictionary *attr = @{
@@ -68,6 +90,11 @@
} }
} }
//
- (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike {
[self configTitle:title currency:@"$" price:price strike:strike];
}
- (void)applySelected:(BOOL)selected animated:(BOOL)animated { - (void)applySelected:(BOOL)selected animated:(BOOL)animated {
NSString *imageName = selected ? @"pay_colorbg_icon" : @"pay_graybg_icon"; NSString *imageName = selected ? @"pay_colorbg_icon" : @"pay_graybg_icon";
void (^changes)(void) = ^{ void (^changes)(void) = ^{
@@ -101,12 +128,32 @@
return _titleLabel; return _titleLabel;
} }
- (UIView *)priceContainer {
if (!_priceContainer) {
_priceContainer = [UIView new];
_priceContainer.backgroundColor = [UIColor whiteColor];
_priceContainer.layer.cornerRadius = 14;
_priceContainer.clipsToBounds = YES;
}
return _priceContainer;
}
- (UILabel *)currencyLabel {
if (!_currencyLabel) {
_currencyLabel = [UILabel new];
_currencyLabel.text = @"$";
_currencyLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_currencyLabel.font = [KBFont medium:14]; //
}
return _currencyLabel;
}
- (UILabel *)priceLabel { - (UILabel *)priceLabel {
if (!_priceLabel) { if (!_priceLabel) {
_priceLabel = [UILabel new]; _priceLabel = [UILabel new];
_priceLabel.text = @"$6.90"; _priceLabel.text = @"6.90";
_priceLabel.textColor = [UIColor colorWithHex:KBBlackValue]; _priceLabel.textColor = [UIColor colorWithHex:KBBlackValue];
_priceLabel.font = [KBFont bold:22]; _priceLabel.font = [KBFont bold:22]; //
} }
return _priceLabel; return _priceLabel;
} }

View File

@@ -118,8 +118,15 @@ static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId";
[self.collectionView reloadData]; [self.collectionView reloadData];
return; return;
} }
self.plans = products ?: @[]; // level=2 SVIP
self.selectedIndex = self.plans.count > 0 ? 1 : NSNotFound; // 1 Month NSMutableArray<KBPayProductModel *> *svipProducts = [NSMutableArray array];
for (KBPayProductModel *product in products) {
if (product.level == 1) {
[svipProducts addObject:product];
}
}
self.plans = svipProducts.copy;
self.selectedIndex = self.plans.count > 1 ? 1 : (self.plans.count > 0 ? 0 : NSNotFound); // 1 Month
[self.collectionView reloadData]; [self.collectionView reloadData];
[self selectCurrentPlanAnimated:NO]; [self selectCurrentPlanAnimated:NO];
[self prepareStoreKitWithPlans:self.plans]; [self prepareStoreKitWithPlans:self.plans];
@@ -231,8 +238,9 @@ static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId";
if (indexPath.item < self.plans.count) { if (indexPath.item < self.plans.count) {
KBPayProductModel *plan = self.plans[indexPath.item]; KBPayProductModel *plan = self.plans[indexPath.item];
NSString *title = [self displayTitleForPlan:plan]; NSString *title = [self displayTitleForPlan:plan];
NSString *price = [plan priceDisplayText]; NSString *currency = plan.currency ?: @"$";
[cell configTitle:title price:price strike:nil]; NSString *price = [plan priceNumberText];
[cell configTitle:title currency:currency price:price strike:nil];
[cell applySelected:(indexPath.item == self.selectedIndex) animated:NO]; [cell applySelected:(indexPath.item == self.selectedIndex) animated:NO];
} }
return cell; return cell;
@@ -264,22 +272,22 @@ static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId";
make.center.equalTo(header); make.center.equalTo(header);
}]; }];
// 线 // 线
UIView *leftLine = [UIView new]; UIImageView *leftLine = [UIImageView new];
leftLine.backgroundColor = [UIColor colorWithHex:0xE5E5E5]; leftLine.image = [UIImage imageNamed:@"pay_leftline_icon"];
[header addSubview:leftLine]; [header addSubview:leftLine];
[leftLine mas_makeConstraints:^(MASConstraintMaker *make) { [leftLine mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(titleLabel.mas_left).offset(-12); make.right.equalTo(titleLabel.mas_left).offset(-12);
make.centerY.equalTo(header); make.centerY.equalTo(header);
make.width.mas_equalTo(40); make.width.mas_equalTo(53);
make.height.mas_equalTo(1); make.height.mas_equalTo(1);
}]; }];
UIView *rightLine = [UIView new]; UIImageView *rightLine = [UIImageView new];
rightLine.backgroundColor = [UIColor colorWithHex:0xE5E5E5]; rightLine.image = [UIImage imageNamed:@"pay_rightline_icon"];
[header addSubview:rightLine]; [header addSubview:rightLine];
[rightLine mas_makeConstraints:^(MASConstraintMaker *make) { [rightLine mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(titleLabel.mas_right).offset(12); make.left.equalTo(titleLabel.mas_right).offset(12);
make.centerY.equalTo(header); make.centerY.equalTo(header);
make.width.mas_equalTo(40); make.width.mas_equalTo(53);
make.height.mas_equalTo(1); make.height.mas_equalTo(1);
}]; }];
return header; return header;
@@ -361,7 +369,8 @@ static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId";
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
if (section == 0) { if (section == 0) {
return UIEdgeInsetsMake(16, 16, 10, 16); // 16Cell17 16+17=33
return UIEdgeInsetsMake(16, 22, 10, 22);
} }
return UIEdgeInsetsMake(0, 16, 20, 16); return UIEdgeInsetsMake(0, 16, 20, 16);
} }