处理svip
This commit is contained in:
@@ -241,6 +241,10 @@
|
||||
04F4C0AA2F32274000E8F08C /* KBPayMainVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F4C0A92F32274000E8F08C /* KBPayMainVC.m */; };
|
||||
04F4C0AD2F32288600E8F08C /* KBPaySvipVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F4C0AC2F32288600E8F08C /* KBPaySvipVC.m */; };
|
||||
04F4C0B02F322EF200E8F08C /* PagingViewTableHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F4C0AF2F322EF200E8F08C /* PagingViewTableHeaderView.m */; };
|
||||
04F4C0B52F33053800E8F08C /* KBSvipBenefitCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F4C0B22F33053800E8F08C /* KBSvipBenefitCell.m */; };
|
||||
04F4C0B62F33053800E8F08C /* KBSvipSubscribeCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F4C0B42F33053800E8F08C /* KBSvipSubscribeCell.m */; };
|
||||
04F4C0BB2F3306CF00E8F08C /* KBSvipFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F4C0BA2F3306CF00E8F08C /* KBSvipFlowLayout.m */; };
|
||||
04F4C0BC2F3306CF00E8F08C /* KBSvipBenefitBgView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04F4C0B82F3306CF00E8F08C /* KBSvipBenefitBgView.m */; };
|
||||
04FC95672EB0546C007BD342 /* KBKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95652EB0546C007BD342 /* KBKey.m */; };
|
||||
04FC956A2EB05497007BD342 /* KBKeyButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC95692EB05497007BD342 /* KBKeyButton.m */; };
|
||||
04FC956D2EB054B7007BD342 /* KBKeyboardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC956C2EB054B7007BD342 /* KBKeyboardView.m */; };
|
||||
@@ -739,6 +743,14 @@
|
||||
04F4C0AC2F32288600E8F08C /* KBPaySvipVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPaySvipVC.m; sourceTree = "<group>"; };
|
||||
04F4C0AE2F322EF200E8F08C /* PagingViewTableHeaderView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PagingViewTableHeaderView.h; sourceTree = "<group>"; };
|
||||
04F4C0AF2F322EF200E8F08C /* PagingViewTableHeaderView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PagingViewTableHeaderView.m; sourceTree = "<group>"; };
|
||||
04F4C0B12F33053800E8F08C /* KBSvipBenefitCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSvipBenefitCell.h; sourceTree = "<group>"; };
|
||||
04F4C0B22F33053800E8F08C /* KBSvipBenefitCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSvipBenefitCell.m; sourceTree = "<group>"; };
|
||||
04F4C0B32F33053800E8F08C /* KBSvipSubscribeCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSvipSubscribeCell.h; sourceTree = "<group>"; };
|
||||
04F4C0B42F33053800E8F08C /* KBSvipSubscribeCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSvipSubscribeCell.m; sourceTree = "<group>"; };
|
||||
04F4C0B72F3306CF00E8F08C /* KBSvipBenefitBgView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSvipBenefitBgView.h; sourceTree = "<group>"; };
|
||||
04F4C0B82F3306CF00E8F08C /* KBSvipBenefitBgView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSvipBenefitBgView.m; sourceTree = "<group>"; };
|
||||
04F4C0B92F3306CF00E8F08C /* KBSvipFlowLayout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBSvipFlowLayout.h; sourceTree = "<group>"; };
|
||||
04F4C0BA2F3306CF00E8F08C /* KBSvipFlowLayout.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBSvipFlowLayout.m; sourceTree = "<group>"; };
|
||||
04FC953A2EAFAE56007BD342 /* KeyBoardPrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyBoardPrefixHeader.pch; sourceTree = "<group>"; };
|
||||
04FC95642EB0546C007BD342 /* KBKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBKey.h; sourceTree = "<group>"; };
|
||||
04FC95652EB0546C007BD342 /* KBKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBKey.m; sourceTree = "<group>"; };
|
||||
@@ -968,6 +980,14 @@
|
||||
04122FB22EC73C0100EF7AB3 /* KBVipReviewListCell.m */,
|
||||
04F4C0AE2F322EF200E8F08C /* PagingViewTableHeaderView.h */,
|
||||
04F4C0AF2F322EF200E8F08C /* PagingViewTableHeaderView.m */,
|
||||
04F4C0B12F33053800E8F08C /* KBSvipBenefitCell.h */,
|
||||
04F4C0B22F33053800E8F08C /* KBSvipBenefitCell.m */,
|
||||
04F4C0B32F33053800E8F08C /* KBSvipSubscribeCell.h */,
|
||||
04F4C0B42F33053800E8F08C /* KBSvipSubscribeCell.m */,
|
||||
04F4C0B72F3306CF00E8F08C /* KBSvipBenefitBgView.h */,
|
||||
04F4C0B82F3306CF00E8F08C /* KBSvipBenefitBgView.m */,
|
||||
04F4C0B92F3306CF00E8F08C /* KBSvipFlowLayout.h */,
|
||||
04F4C0BA2F3306CF00E8F08C /* KBSvipFlowLayout.m */,
|
||||
);
|
||||
path = V;
|
||||
sourceTree = "<group>";
|
||||
@@ -2540,6 +2560,8 @@
|
||||
047C655C2EBCD0F80035E841 /* UIView+KBShadow.m in Sources */,
|
||||
04E038DD2F20C420002CA5A0 /* VoiceChatStreamingManager.m in Sources */,
|
||||
04E038DE2F20C420002CA5A0 /* VoiceChatWebSocketClient.m in Sources */,
|
||||
04F4C0B52F33053800E8F08C /* KBSvipBenefitCell.m in Sources */,
|
||||
04F4C0B62F33053800E8F08C /* KBSvipSubscribeCell.m in Sources */,
|
||||
049FB2262EC3136D00FAB05D /* KBPersonInfoItemCell.m in Sources */,
|
||||
048908C32EBE32B800FABA60 /* KBSearchVC.m in Sources */,
|
||||
049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */,
|
||||
@@ -2609,6 +2631,8 @@
|
||||
047C65502EBCBA9E0035E841 /* KBShopVC.m in Sources */,
|
||||
0477BE042EBC83130055D639 /* HomeMainVC.m in Sources */,
|
||||
0477BDFD2EBC6A170055D639 /* HomeHotVC.m in Sources */,
|
||||
04F4C0BB2F3306CF00E8F08C /* KBSvipFlowLayout.m in Sources */,
|
||||
04F4C0BC2F3306CF00E8F08C /* KBSvipBenefitBgView.m in Sources */,
|
||||
04E039522F2387D2002CA5A0 /* KBAiChatMessage.m in Sources */,
|
||||
0460869A2F19238500757C95 /* KBAiWaveformView.m in Sources */,
|
||||
0460869C2F19238500757C95 /* KBAiRecordButton.m in Sources */,
|
||||
|
||||
16
keyBoard/Class/Pay/V/KBSvipBenefitBgView.h
Normal file
16
keyBoard/Class/Pay/V/KBSvipBenefitBgView.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// KBSvipBenefitBgView.h
|
||||
// keyBoard
|
||||
//
|
||||
// 权益列表背景装饰视图
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBSvipBenefitBgView : UICollectionReusableView
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
21
keyBoard/Class/Pay/V/KBSvipBenefitBgView.m
Normal file
21
keyBoard/Class/Pay/V/KBSvipBenefitBgView.m
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// KBSvipBenefitBgView.m
|
||||
// keyBoard
|
||||
//
|
||||
// 权益列表背景装饰视图:白色背景 + 15圆角
|
||||
//
|
||||
|
||||
#import "KBSvipBenefitBgView.h"
|
||||
|
||||
@implementation KBSvipBenefitBgView
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
self.layer.cornerRadius = 15;
|
||||
self.layer.masksToBounds = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
17
keyBoard/Class/Pay/V/KBSvipBenefitCell.h
Normal file
17
keyBoard/Class/Pay/V/KBSvipBenefitCell.h
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// KBSvipBenefitCell.h
|
||||
// keyBoard
|
||||
//
|
||||
// SVIP 权益项 Cell:左侧图标 + 文字 + 右侧勾选
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBSvipBenefitCell : UICollectionViewCell
|
||||
/// 配置权益项
|
||||
- (void)configWithIcon:(NSString *)iconName title:(NSString *)title;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
88
keyBoard/Class/Pay/V/KBSvipBenefitCell.m
Normal file
88
keyBoard/Class/Pay/V/KBSvipBenefitCell.m
Normal file
@@ -0,0 +1,88 @@
|
||||
//
|
||||
// KBSvipBenefitCell.m
|
||||
// keyBoard
|
||||
//
|
||||
// SVIP 权益项样式:左侧图标 + 文字 + 右侧勾选
|
||||
//
|
||||
|
||||
#import "KBSvipBenefitCell.h"
|
||||
|
||||
@interface KBSvipBenefitCell ()
|
||||
@property (nonatomic, strong) UIImageView *iconView; // 左侧图标
|
||||
@property (nonatomic, strong) UILabel *titleLabel; // 权益文字
|
||||
@property (nonatomic, strong) UIImageView *checkView; // 右侧勾选
|
||||
@end
|
||||
|
||||
@implementation KBSvipBenefitCell
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
self.contentView.backgroundColor = [UIColor clearColor];
|
||||
|
||||
[self.contentView addSubview:self.iconView];
|
||||
[self.contentView addSubview:self.titleLabel];
|
||||
[self.contentView addSubview:self.checkView];
|
||||
|
||||
[self.iconView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(self.contentView).offset(16);
|
||||
make.centerY.equalTo(self.contentView);
|
||||
make.width.height.mas_equalTo(40);
|
||||
}];
|
||||
|
||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(self.iconView.mas_right).offset(12);
|
||||
make.centerY.equalTo(self.contentView);
|
||||
make.right.lessThanOrEqualTo(self.checkView.mas_left).offset(-12);
|
||||
}];
|
||||
|
||||
[self.checkView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.right.equalTo(self.contentView).offset(-16);
|
||||
make.centerY.equalTo(self.contentView);
|
||||
make.width.height.mas_equalTo(20);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)configWithIcon:(NSString *)iconName title:(NSString *)title {
|
||||
if (iconName.length) {
|
||||
self.iconView.image = [UIImage imageNamed:iconName];
|
||||
}
|
||||
self.titleLabel.text = title.length ? title : @"";
|
||||
}
|
||||
|
||||
#pragma mark - Lazy
|
||||
- (UIImageView *)iconView {
|
||||
if (!_iconView) {
|
||||
_iconView = [UIImageView new];
|
||||
_iconView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
_iconView.layer.cornerRadius = 8;
|
||||
_iconView.clipsToBounds = YES;
|
||||
}
|
||||
return _iconView;
|
||||
}
|
||||
|
||||
- (UILabel *)titleLabel {
|
||||
if (!_titleLabel) {
|
||||
_titleLabel = [UILabel new];
|
||||
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||||
_titleLabel.font = [KBFont regular:14];
|
||||
}
|
||||
return _titleLabel;
|
||||
}
|
||||
|
||||
- (UIImageView *)checkView {
|
||||
if (!_checkView) {
|
||||
_checkView = [UIImageView new];
|
||||
_checkView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
// 使用 SF Symbol 勾选图标
|
||||
if (@available(iOS 13.0, *)) {
|
||||
UIImageSymbolConfiguration *config = [UIImageSymbolConfiguration configurationWithWeight:UIImageSymbolWeightMedium];
|
||||
_checkView.image = [UIImage systemImageNamed:@"checkmark" withConfiguration:config];
|
||||
}
|
||||
_checkView.tintColor = [UIColor colorWithHex:KBColorValue];
|
||||
}
|
||||
return _checkView;
|
||||
}
|
||||
|
||||
@end
|
||||
19
keyBoard/Class/Pay/V/KBSvipFlowLayout.h
Normal file
19
keyBoard/Class/Pay/V/KBSvipFlowLayout.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// KBSvipFlowLayout.h
|
||||
// keyBoard
|
||||
//
|
||||
// SVIP 页面自定义布局,支持 Section 背景装饰视图
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBSvipFlowLayout : UICollectionViewFlowLayout
|
||||
|
||||
/// 需要添加背景的 Section 索引(默认 Section 1)
|
||||
@property (nonatomic, assign) NSInteger decorationSection;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
90
keyBoard/Class/Pay/V/KBSvipFlowLayout.m
Normal file
90
keyBoard/Class/Pay/V/KBSvipFlowLayout.m
Normal file
@@ -0,0 +1,90 @@
|
||||
//
|
||||
// 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
|
||||
19
keyBoard/Class/Pay/V/KBSvipSubscribeCell.h
Normal file
19
keyBoard/Class/Pay/V/KBSvipSubscribeCell.h
Normal file
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// KBSvipSubscribeCell.h
|
||||
// keyBoard
|
||||
//
|
||||
// SVIP 订阅选项 Cell:横向排列,选中时绿色边框
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBSvipSubscribeCell : UICollectionViewCell
|
||||
/// 配置展示文案
|
||||
- (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike;
|
||||
/// 同步选中态
|
||||
- (void)applySelected:(BOOL)selected animated:(BOOL)animated;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
130
keyBoard/Class/Pay/V/KBSvipSubscribeCell.m
Normal file
130
keyBoard/Class/Pay/V/KBSvipSubscribeCell.m
Normal file
@@ -0,0 +1,130 @@
|
||||
//
|
||||
// KBSvipSubscribeCell.m
|
||||
// keyBoard
|
||||
//
|
||||
// SVIP 订阅选项样式,横向排列,选中时绿色边框
|
||||
//
|
||||
|
||||
#import "KBSvipSubscribeCell.h"
|
||||
|
||||
@interface KBSvipSubscribeCell ()
|
||||
@property (nonatomic, strong) UIView *cardView; // 白色卡片背景
|
||||
@property (nonatomic, strong) UILabel *titleLabel; // "1 Week" / "1 Month" / "1 Year"
|
||||
@property (nonatomic, strong) UILabel *priceLabel; // "$6.90"
|
||||
@property (nonatomic, strong) UILabel *strikeLabel; // 删除线原价
|
||||
@end
|
||||
|
||||
@implementation KBSvipSubscribeCell
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
self.contentView.backgroundColor = [UIColor clearColor];
|
||||
|
||||
[self.contentView addSubview:self.cardView];
|
||||
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(self.contentView);
|
||||
}];
|
||||
|
||||
[self.cardView addSubview:self.titleLabel];
|
||||
[self.cardView addSubview:self.priceLabel];
|
||||
[self.cardView addSubview:self.strikeLabel];
|
||||
|
||||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.equalTo(self.cardView);
|
||||
make.top.equalTo(self.cardView).offset(12);
|
||||
}];
|
||||
[self.priceLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.equalTo(self.cardView);
|
||||
make.top.equalTo(self.titleLabel.mas_bottom).offset(8);
|
||||
}];
|
||||
[self.strikeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.equalTo(self.cardView);
|
||||
make.top.equalTo(self.priceLabel.mas_bottom).offset(4);
|
||||
}];
|
||||
|
||||
// 基于 CALayer 的边框
|
||||
self.cardView.layer.borderWidth = 1.5;
|
||||
self.cardView.layer.borderColor = [UIColor colorWithWhite:0.9 alpha:1.0].CGColor;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)prepareForReuse {
|
||||
[super prepareForReuse];
|
||||
[self applySelected:NO animated:NO];
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected {
|
||||
[super setSelected:selected];
|
||||
[self applySelected:selected animated:NO];
|
||||
}
|
||||
|
||||
- (void)configTitle:(NSString *)title price:(NSString *)price strike:(nullable NSString *)strike {
|
||||
self.titleLabel.text = title.length ? title : @"1 Month";
|
||||
self.priceLabel.text = price.length ? price : @"$6.90";
|
||||
self.strikeLabel.hidden = (strike.length == 0);
|
||||
if (strike.length) {
|
||||
NSDictionary *attr = @{
|
||||
NSStrikethroughStyleAttributeName: @(NSUnderlineStyleSingle),
|
||||
NSForegroundColorAttributeName: [UIColor colorWithHex:0x999999]
|
||||
};
|
||||
self.strikeLabel.attributedText = [[NSAttributedString alloc] initWithString:strike attributes:attr];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applySelected:(BOOL)selected animated:(BOOL)animated {
|
||||
CGColorRef color = (selected ? [UIColor colorWithHex:KBColorValue].CGColor : [UIColor colorWithWhite:0.9 alpha:1.0].CGColor);
|
||||
UIColor *bgColor = selected ? [UIColor colorWithHex:0xE8FFF6] : [UIColor whiteColor];
|
||||
void (^changes)(void) = ^{
|
||||
self.cardView.layer.borderColor = color;
|
||||
self.cardView.backgroundColor = bgColor;
|
||||
};
|
||||
if (animated) {
|
||||
[UIView animateWithDuration:0.2 animations:changes];
|
||||
} else {
|
||||
changes();
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Lazy
|
||||
- (UIView *)cardView {
|
||||
if (!_cardView) {
|
||||
_cardView = [UIView new];
|
||||
_cardView.backgroundColor = [UIColor whiteColor];
|
||||
_cardView.layer.cornerRadius = 12;
|
||||
_cardView.clipsToBounds = YES;
|
||||
}
|
||||
return _cardView;
|
||||
}
|
||||
|
||||
- (UILabel *)titleLabel {
|
||||
if (!_titleLabel) {
|
||||
_titleLabel = [UILabel new];
|
||||
_titleLabel.text = @"1 Month";
|
||||
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||||
_titleLabel.font = [KBFont medium:13];
|
||||
}
|
||||
return _titleLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)priceLabel {
|
||||
if (!_priceLabel) {
|
||||
_priceLabel = [UILabel new];
|
||||
_priceLabel.text = @"$6.90";
|
||||
_priceLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||||
_priceLabel.font = [KBFont bold:22];
|
||||
}
|
||||
return _priceLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)strikeLabel {
|
||||
if (!_strikeLabel) {
|
||||
_strikeLabel = [UILabel new];
|
||||
_strikeLabel.text = @"$4.49";
|
||||
_strikeLabel.font = [KBFont regular:12];
|
||||
_strikeLabel.textColor = [UIColor colorWithHex:0x999999];
|
||||
}
|
||||
return _strikeLabel;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -6,30 +6,374 @@
|
||||
//
|
||||
|
||||
#import "KBPaySvipVC.h"
|
||||
#import "KBSvipSubscribeCell.h"
|
||||
#import "KBSvipBenefitCell.h"
|
||||
#import "KBSvipFlowLayout.h"
|
||||
#import "PayVM.h"
|
||||
#import "KBPayProductModel.h"
|
||||
#import "KBBizCode.h"
|
||||
#import "keyBoard-Swift.h"
|
||||
#import <MJExtension/MJExtension.h>
|
||||
|
||||
@interface KBPaySvipVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||
static NSString * const kKBSvipSubscribeCellId = @"kKBSvipSubscribeCellId";
|
||||
static NSString * const kKBSvipBenefitCellId = @"kKBSvipBenefitCellId";
|
||||
static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId";
|
||||
|
||||
@interface KBPaySvipVC () <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||
@property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
|
||||
|
||||
/// 1:UI 控件
|
||||
@property (nonatomic, strong) UICollectionView *collectionView;
|
||||
@property (nonatomic, strong) UIButton *payButton;
|
||||
@property (nonatomic, strong) UILabel *agreementLabel;
|
||||
@property (nonatomic, strong) UIButton *agreementButton;
|
||||
|
||||
/// 2:数据
|
||||
@property (nonatomic, strong) NSArray<KBPayProductModel *> *plans;
|
||||
@property (nonatomic, assign) NSInteger selectedIndex;
|
||||
@property (nonatomic, strong) NSArray<NSDictionary *> *benefits;
|
||||
@property (nonatomic, strong) PayVM *payVM;
|
||||
@end
|
||||
|
||||
@implementation KBPaySvipVC
|
||||
|
||||
#pragma mark - Life Cycle
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view.
|
||||
// 懒加载 collectionView,并添加到视图
|
||||
|
||||
/// 1:控件初始化
|
||||
[self setupUI];
|
||||
/// 2:数据初始化
|
||||
[self setupData];
|
||||
/// 3:加载数据
|
||||
[self loadData];
|
||||
}
|
||||
|
||||
#pragma mark - 1:控件初始化
|
||||
|
||||
- (void)setupUI {
|
||||
self.view.backgroundColor = [UIColor colorWithHex:0xF6F7FB];
|
||||
|
||||
[self.view addSubview:self.payButton];
|
||||
[self.view addSubview:self.agreementLabel];
|
||||
[self.view addSubview:self.agreementButton];
|
||||
[self.view addSubview:self.collectionView];
|
||||
|
||||
[self.agreementButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.equalTo(self.view);
|
||||
make.bottom.equalTo(self.view).offset(-KB_SAFE_BOTTOM - 15);
|
||||
}];
|
||||
|
||||
[self.agreementLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.equalTo(self.view);
|
||||
make.bottom.equalTo(self.agreementButton.mas_top).offset(0);
|
||||
}];
|
||||
|
||||
[self.payButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(self.view).offset(24);
|
||||
make.right.equalTo(self.view).offset(-24);
|
||||
make.bottom.equalTo(self.agreementLabel.mas_top).offset(-14);
|
||||
make.height.mas_equalTo(58);
|
||||
}];
|
||||
|
||||
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(self.view); // mas 布局:铺满
|
||||
make.left.right.top.equalTo(self.view);
|
||||
make.bottom.equalTo(self.payButton.mas_top).offset(-16);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - 2:数据初始化
|
||||
|
||||
- (void)setupData {
|
||||
self.payVM = [PayVM new];
|
||||
self.plans = @[];
|
||||
self.selectedIndex = NSNotFound;
|
||||
|
||||
// 权益列表数据(使用现有图标资源)
|
||||
self.benefits = @[
|
||||
@{@"icon": @"pay_ai_icon", @"title": KBLocalized(@"Wireless Sub-ai Dialogue")},
|
||||
@{@"icon": @"pay_keyboard_icon", @"title": KBLocalized(@"Personalized Keyboard")},
|
||||
@{@"icon": @"pay_chat_icon", @"title": KBLocalized(@"Chat Persona")},
|
||||
@{@"icon": @"pay_emotion_icon", @"title": KBLocalized(@"Emotional Counseling")},
|
||||
@{@"icon": @"pay_chat_icon", @"title": KBLocalized(@"Longer Chat History")},
|
||||
@{@"icon": @"pay_chat_icon", @"title": KBLocalized(@"Unlimited Chatting")},
|
||||
@{@"icon": @"pay_ai_icon", @"title": KBLocalized(@"Chat Without Speed Limits")},
|
||||
@{@"icon": @"pay_vip_icon", @"title": KBLocalized(@"Coming Soon")},
|
||||
];
|
||||
}
|
||||
|
||||
#pragma mark - 3:加载数据
|
||||
|
||||
- (void)loadData {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self.payVM fetchSubscriptionProductsNeedShow:YES completion:^(NSInteger sta, NSString * _Nullable msg, NSArray<KBPayProductModel *> * _Nullable products) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
__strong typeof(weakSelf) self = weakSelf;
|
||||
if (!self) { return; }
|
||||
if (sta != KBBizCodeSuccess || ![products isKindOfClass:NSArray.class]) {
|
||||
self.plans = @[];
|
||||
self.selectedIndex = NSNotFound;
|
||||
[self.collectionView reloadData];
|
||||
return;
|
||||
}
|
||||
self.plans = products ?: @[];
|
||||
self.selectedIndex = self.plans.count > 0 ? 1 : NSNotFound; // 默认选中第二个(1 Month)
|
||||
[self.collectionView reloadData];
|
||||
[self selectCurrentPlanAnimated:NO];
|
||||
[self prepareStoreKitWithPlans:self.plans];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Private Methods
|
||||
|
||||
- (void)prepareStoreKitWithPlans:(NSArray<KBPayProductModel *> *)plans {
|
||||
if (![plans isKindOfClass:NSArray.class] || plans.count == 0) { return; }
|
||||
NSMutableArray<NSString *> *ids = [NSMutableArray array];
|
||||
for (KBPayProductModel *plan in plans) {
|
||||
if (![plan isKindOfClass:KBPayProductModel.class]) { continue; }
|
||||
if (plan.productId.length) {
|
||||
[ids addObject:plan.productId];
|
||||
}
|
||||
}
|
||||
if (ids.count == 0) { return; }
|
||||
[[KBStoreKitBridge shared] prepareWithProductIds:ids completion:nil];
|
||||
}
|
||||
|
||||
- (void)selectCurrentPlanAnimated:(BOOL)animated {
|
||||
if (self.selectedIndex == NSNotFound) { return; }
|
||||
if (self.selectedIndex < 0 || self.selectedIndex >= self.plans.count) { return; }
|
||||
NSIndexPath *ip = [NSIndexPath indexPathForItem:self.selectedIndex inSection:0];
|
||||
[self.collectionView selectItemAtIndexPath:ip animated:animated scrollPosition:UICollectionViewScrollPositionNone];
|
||||
KBSvipSubscribeCell *cell = (KBSvipSubscribeCell *)[self.collectionView cellForItemAtIndexPath:ip];
|
||||
if ([cell isKindOfClass:KBSvipSubscribeCell.class]) {
|
||||
[cell applySelected:YES animated:animated];
|
||||
}
|
||||
}
|
||||
|
||||
- (KBPayProductModel *)currentSelectedPlan {
|
||||
if (self.selectedIndex == NSNotFound) { return nil; }
|
||||
if (self.selectedIndex < 0 || self.selectedIndex >= self.plans.count) { return nil; }
|
||||
return self.plans[self.selectedIndex];
|
||||
}
|
||||
|
||||
- (NSString *)displayTitleForPlan:(KBPayProductModel *)plan {
|
||||
if (!plan) { return @""; }
|
||||
if (plan.productDescription.length) { return plan.productDescription; }
|
||||
NSString *name = plan.name ?: @"";
|
||||
NSString *unit = plan.unit ?: @"";
|
||||
if (name.length && unit.length) { return [NSString stringWithFormat:@"%@ %@", name, unit]; }
|
||||
if (name.length) { return name; }
|
||||
if (unit.length) { return unit; }
|
||||
return KBLocalized(@"Subscription");
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
|
||||
- (void)onTapPayButton {
|
||||
KBPayProductModel *plan = [self currentSelectedPlan];
|
||||
if (!plan) {
|
||||
[KBHUD showInfo:KBLocalized(@"Please select a product")];
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *extra = [NSMutableDictionary dictionary];
|
||||
if ([plan.productId isKindOfClass:NSString.class] && plan.productId.length > 0) {
|
||||
extra[@"product_id"] = plan.productId;
|
||||
}
|
||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_svip_pay_btn"
|
||||
pageId:@"svip_pay"
|
||||
elementId:@"pay_btn"
|
||||
extra:extra.copy
|
||||
completion:nil];
|
||||
|
||||
NSString *productId = plan.productId;
|
||||
if (productId.length == 0) {
|
||||
[KBHUD showInfo:KBLocalized(@"Product unavailable")];
|
||||
return;
|
||||
}
|
||||
|
||||
[KBHUD show];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[[KBStoreKitBridge shared] purchaseWithProductId:productId completion:^(BOOL success, NSString * _Nullable message) {
|
||||
__strong typeof(weakSelf) self = weakSelf;
|
||||
[KBHUD dismiss];
|
||||
[KBHUD showInfo:KBLocalized(message)];
|
||||
if (!self || !success) { return; }
|
||||
[self selectCurrentPlanAnimated:NO];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)agreementButtonAction {
|
||||
[KBHUD showInfo:KBLocalized(@"Open agreement")];
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionView DataSource
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
|
||||
// Section 0: 订阅选项(横向)
|
||||
// Section 1: 权益列表
|
||||
return 2;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
|
||||
if (section == 0) {
|
||||
return self.plans.count;
|
||||
}
|
||||
return self.benefits.count;
|
||||
}
|
||||
|
||||
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (indexPath.section == 0) {
|
||||
KBSvipSubscribeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kKBSvipSubscribeCellId forIndexPath:indexPath];
|
||||
if (indexPath.item < self.plans.count) {
|
||||
KBPayProductModel *plan = self.plans[indexPath.item];
|
||||
NSString *title = [self displayTitleForPlan:plan];
|
||||
NSString *price = [plan priceDisplayText];
|
||||
[cell configTitle:title price:price strike:nil];
|
||||
[cell applySelected:(indexPath.item == self.selectedIndex) animated:NO];
|
||||
}
|
||||
return cell;
|
||||
} else {
|
||||
KBSvipBenefitCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kKBSvipBenefitCellId forIndexPath:indexPath];
|
||||
if (indexPath.item < self.benefits.count) {
|
||||
NSDictionary *benefit = self.benefits[indexPath.item];
|
||||
[cell configWithIcon:benefit[@"icon"] title:benefit[@"title"]];
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
|
||||
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
|
||||
if (indexPath.section == 1 && [kind isEqualToString:UICollectionElementKindSectionHeader]) {
|
||||
UICollectionReusableView *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kKBSvipBenefitHeaderId forIndexPath:indexPath];
|
||||
// 清除旧的子视图
|
||||
for (UIView *subview in header.subviews) {
|
||||
[subview removeFromSuperview];
|
||||
}
|
||||
// 添加标题
|
||||
UILabel *titleLabel = [UILabel new];
|
||||
titleLabel.text = KBLocalized(@"Membership Benefits");
|
||||
titleLabel.textColor = [UIColor colorWithHex:0x999999];
|
||||
titleLabel.font = [KBFont medium:13];
|
||||
titleLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[header addSubview:titleLabel];
|
||||
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.center.equalTo(header);
|
||||
}];
|
||||
// 左右横线
|
||||
UIView *leftLine = [UIView new];
|
||||
leftLine.backgroundColor = [UIColor colorWithHex:0xE5E5E5];
|
||||
[header addSubview:leftLine];
|
||||
[leftLine mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.right.equalTo(titleLabel.mas_left).offset(-12);
|
||||
make.centerY.equalTo(header);
|
||||
make.width.mas_equalTo(40);
|
||||
make.height.mas_equalTo(1);
|
||||
}];
|
||||
UIView *rightLine = [UIView new];
|
||||
rightLine.backgroundColor = [UIColor colorWithHex:0xE5E5E5];
|
||||
[header addSubview:rightLine];
|
||||
[rightLine mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(titleLabel.mas_right).offset(12);
|
||||
make.centerY.equalTo(header);
|
||||
make.width.mas_equalTo(40);
|
||||
make.height.mas_equalTo(1);
|
||||
}];
|
||||
return header;
|
||||
}
|
||||
return [UICollectionReusableView new];
|
||||
}
|
||||
|
||||
#pragma mark - UICollectionView Delegate
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (indexPath.section != 0 || indexPath.item >= self.plans.count) { return; }
|
||||
if (self.selectedIndex == indexPath.item) { return; }
|
||||
|
||||
NSInteger old = self.selectedIndex;
|
||||
self.selectedIndex = indexPath.item;
|
||||
|
||||
KBPayProductModel *plan = self.plans[indexPath.item];
|
||||
NSMutableDictionary *extra = [NSMutableDictionary dictionary];
|
||||
extra[@"index"] = @(indexPath.item);
|
||||
if ([plan.productId isKindOfClass:NSString.class] && plan.productId.length > 0) {
|
||||
extra[@"product_id"] = plan.productId;
|
||||
}
|
||||
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_svip_select_plan"
|
||||
pageId:@"svip_pay"
|
||||
elementId:@"plan_item"
|
||||
extra:extra.copy
|
||||
completion:nil];
|
||||
|
||||
KBSvipSubscribeCell *newCell = (KBSvipSubscribeCell *)[collectionView cellForItemAtIndexPath:indexPath];
|
||||
[newCell applySelected:YES animated:YES];
|
||||
|
||||
if (old >= 0 && old < self.plans.count) {
|
||||
NSIndexPath *oldIP = [NSIndexPath indexPathForItem:old inSection:0];
|
||||
KBSvipSubscribeCell *oldCell = (KBSvipSubscribeCell *)[collectionView cellForItemAtIndexPath:oldIP];
|
||||
[oldCell applySelected:NO animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
if (indexPath.section == 0 && indexPath.item < self.plans.count && [cell isKindOfClass:KBSvipSubscribeCell.class]) {
|
||||
BOOL sel = (indexPath.item == self.selectedIndex);
|
||||
KBSvipSubscribeCell *c = (KBSvipSubscribeCell *)cell;
|
||||
if (sel) {
|
||||
[collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
|
||||
}
|
||||
[c applySelected:sel animated:NO];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - FlowLayout
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
|
||||
CGFloat screenW = KB_SCREEN_WIDTH;
|
||||
if (indexPath.section == 0) {
|
||||
// 订阅选项:横向三等分
|
||||
CGFloat itemW = (screenW - 32 - 20) / 3.0; // 左右各16,间距10*2
|
||||
return CGSizeMake(itemW, 90);
|
||||
} else {
|
||||
// 权益项
|
||||
return CGSizeMake(screenW - 32, 56);
|
||||
}
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
|
||||
if (section == 1) {
|
||||
return CGSizeMake(KB_SCREEN_WIDTH, 50);
|
||||
}
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
|
||||
if (section == 0) { return 10; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
|
||||
if (section == 0) { return 10; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
|
||||
if (section == 0) {
|
||||
return UIEdgeInsetsMake(16, 16, 10, 16);
|
||||
}
|
||||
return UIEdgeInsetsMake(0, 16, 20, 16);
|
||||
}
|
||||
|
||||
#pragma mark - UIScrollView Delegate(转发给分页容器)
|
||||
|
||||
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
|
||||
!self.scrollCallback ?: self.scrollCallback(scrollView);
|
||||
}
|
||||
|
||||
#pragma mark - JXPagingViewListViewDelegate
|
||||
|
||||
- (UIView *)listView { return self.view; }
|
||||
- (UIScrollView *)listScrollView { return self.collectionView; }
|
||||
- (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback { self.scrollCallback = callback; }
|
||||
@@ -38,21 +382,60 @@
|
||||
- (void)listWillDisappear { NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); }
|
||||
- (void)listDidDisappear { NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); }
|
||||
|
||||
|
||||
#pragma mark - Lazy
|
||||
|
||||
- (UICollectionView *)collectionView {
|
||||
if (!_collectionView) {
|
||||
UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
|
||||
KBSvipFlowLayout *layout = [KBSvipFlowLayout new];
|
||||
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
|
||||
layout.decorationSection = 1; // Section 1 添加背景
|
||||
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
|
||||
_collectionView.backgroundColor = [UIColor clearColor];
|
||||
// _collectionView.dataSource = self;
|
||||
// _collectionView.delegate = self;
|
||||
// 注册皮肤卡片 cell
|
||||
// [_collectionView registerClass:KBSkinCardCell.class forCellWithReuseIdentifier:@"KBSkinCardCell"]; // 复用标识
|
||||
_collectionView.dataSource = self;
|
||||
_collectionView.delegate = self;
|
||||
_collectionView.alwaysBounceVertical = YES;
|
||||
_collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
[_collectionView registerClass:KBSvipSubscribeCell.class forCellWithReuseIdentifier:kKBSvipSubscribeCellId];
|
||||
[_collectionView registerClass:KBSvipBenefitCell.class forCellWithReuseIdentifier:kKBSvipBenefitCellId];
|
||||
[_collectionView registerClass:UICollectionReusableView.class forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:kKBSvipBenefitHeaderId];
|
||||
}
|
||||
return _collectionView;
|
||||
}
|
||||
|
||||
- (UIButton *)payButton {
|
||||
if (!_payButton) {
|
||||
_payButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_payButton setTitle:KBLocalized(@"Recharge Now") forState:UIControlStateNormal];
|
||||
[_payButton setTitleColor:[UIColor colorWithHex:KBBlackValue] forState:UIControlStateNormal];
|
||||
_payButton.titleLabel.font = [KBFont medium:15];
|
||||
_payButton.layer.cornerRadius = 29;
|
||||
_payButton.clipsToBounds = YES;
|
||||
_payButton.backgroundColor = [UIColor colorWithHex:0x222222];
|
||||
[_payButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
|
||||
[_payButton addTarget:self action:@selector(onTapPayButton) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _payButton;
|
||||
}
|
||||
|
||||
- (UILabel *)agreementLabel {
|
||||
if (!_agreementLabel) {
|
||||
_agreementLabel = [UILabel new];
|
||||
_agreementLabel.text = KBLocalized(@"By Clicking \"pay\", You Indicate Your Agreement To The");
|
||||
_agreementLabel.font = [KBFont regular:12];
|
||||
_agreementLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||||
}
|
||||
return _agreementLabel;
|
||||
}
|
||||
|
||||
- (UIButton *)agreementButton {
|
||||
if (!_agreementButton) {
|
||||
_agreementButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[_agreementButton setTitle:KBLocalized(@"《Embership Agreement》") forState:UIControlStateNormal];
|
||||
[_agreementButton setTitleColor:[UIColor colorWithHex:KBColorValue] forState:UIControlStateNormal];
|
||||
_agreementButton.titleLabel.font = [KBFont regular:12];
|
||||
[_agreementButton addTarget:self action:@selector(agreementButtonAction) forControlEvents:UIControlEventTouchUpInside];
|
||||
}
|
||||
return _agreementButton;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user