This commit is contained in:
2026-02-04 14:59:02 +08:00
parent 879dbb860c
commit e50eaecbd9
39 changed files with 360 additions and 75 deletions

View File

@@ -11,7 +11,7 @@
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
self.backgroundColor = [UIColor colorWithHex:0xF6F7FB];
self.layer.cornerRadius = 15;
self.layer.masksToBounds = YES;
}

View File

@@ -8,6 +8,8 @@
#import "KBSvipBenefitCell.h"
@interface KBSvipBenefitCell ()
@property (nonatomic, strong) UIView *coverView; //
@property (nonatomic, strong) UIImageView *iconView; //
@property (nonatomic, strong) UILabel *titleLabel; //
@property (nonatomic, strong) UIImageView *checkView; //
@@ -18,26 +20,33 @@
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.contentView.backgroundColor = [UIColor clearColor];
[self.contentView addSubview:self.coverView];
[self.contentView addSubview:self.iconView];
[self.contentView addSubview:self.titleLabel];
[self.contentView addSubview:self.checkView];
[self.coverView addSubview:self.titleLabel];
[self.coverView addSubview:self.checkView];
[self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.contentView).inset(8);
make.centerY.equalTo(self.contentView);
make.height.mas_equalTo(46);
}];
[self.iconView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentView).offset(16);
make.centerY.equalTo(self.contentView);
make.width.height.mas_equalTo(40);
make.left.equalTo(self.coverView).offset(16);
make.top.equalTo(self.contentView);
make.width.height.mas_equalTo(38);
}];
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.iconView.mas_right).offset(12);
make.centerY.equalTo(self.contentView);
make.centerY.equalTo(self.coverView);
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.right.equalTo(self.coverView).offset(-16);
make.centerY.equalTo(self.coverView);
make.width.height.mas_equalTo(20);
}];
}
@@ -75,14 +84,20 @@
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];
_checkView.image = [UIImage imageNamed:@"pay_oks_icon"];
}
return _checkView;
}
- (UIView *)coverView{
if (!_coverView) {
_coverView = [[UIView alloc] init];
_coverView.backgroundColor = [UIColor whiteColor];
_coverView.layer.cornerRadius = 8;
_coverView.layer.masksToBounds = true;
}
return _coverView;
}
@end

View File

@@ -27,7 +27,7 @@
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor clearColor];
self.backgroundColor = [UIColor colorWithHex:0xF6F7FB];
[self addSubview:self.containerView];
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -47,7 +47,7 @@
CGFloat spacing = 16;
[g1 mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.containerView).inset(KBFit(27));
make.top.equalTo(self.containerView).offset(KB_NAV_TOTAL_HEIGHT + 25);
make.top.equalTo(self.containerView).offset(25);
make.height.mas_equalTo(((KBFit(122))));
}];
[g2 mas_makeConstraints:^(MASConstraintMaker *make) {

View File

@@ -23,6 +23,7 @@
#import "JXPagerView.h"
#import "PagingViewTableHeaderView.h"
#import "JXCategoryTitleView.h"
#import "keyBoard-Swift.h"
static const CGFloat JXTableHeaderViewHeight = 224;
static const CGFloat JXheightForHeaderInSection = 39;
@@ -31,6 +32,7 @@ static const CGFloat JXheightForHeaderInSection = 39;
@property (nonatomic, strong) JXPagerView *pagerView;
@property (nonatomic, strong) PagingViewTableHeaderView *userHeaderView;
//@property (nonatomic, strong, readonly) JXCategoryTitleView *categoryView;
@property (nonatomic, strong) UIView *categoryContainer; // categoryView
@property (nonatomic, strong) JXCategoryImageView *myCategoryView;
@property (nonatomic, assign) BOOL isNeedFooter;
@@ -41,6 +43,7 @@ static const CGFloat JXheightForHeaderInSection = 39;
@property (nonatomic, strong) UIView *naviBGView;
@property (nonatomic, strong) UIButton *closeButton; //
@property (nonatomic, strong) UIButton *restoreButton;
@end
@@ -56,8 +59,23 @@ static const CGFloat JXheightForHeaderInSection = 39;
NSArray *selectedImageNames = @[@"VIP_Selected_icon", @"SVIP_Selected_icon"];
_userHeaderView = [[PagingViewTableHeaderView alloc] init];
self.myCategoryView = [[JXCategoryImageView alloc] initWithFrame:CGRectMake(24, 0, KB_SCREEN_WIDTH - 48, JXheightForHeaderInSection)];
self.myCategoryView.backgroundColor = [UIColor redColor];
//
self.categoryContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KB_SCREEN_WIDTH, JXheightForHeaderInSection)];
self.categoryContainer.backgroundColor = [UIColor clearColor];
// categoryView
self.myCategoryView = [[JXCategoryImageView alloc] init];
self.myCategoryView.backgroundColor = [UIColor whiteColor];
self.myCategoryView.layer.cornerRadius = JXheightForHeaderInSection * 0.5;
self.myCategoryView.layer.masksToBounds = true;
[self.categoryContainer addSubview:self.myCategoryView];
[self.myCategoryView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.categoryContainer).offset(KBFit(24));
make.right.equalTo(self.categoryContainer).offset(-KBFit(24));
make.top.bottom.equalTo(self.categoryContainer);
}];
self.myCategoryView.imageInfoArray = self.imageNames;
self.myCategoryView.selectedImageInfoArray = selectedImageNames;
self.myCategoryView.loadImageBlock = ^(UIImageView *imageView, id info) {
@@ -66,6 +84,10 @@ static const CGFloat JXheightForHeaderInSection = 39;
};
// self.myCategoryView.imageZoomEnabled = YES;
self.myCategoryView.imageCornerRadius = 0;
self.myCategoryView.contentEdgeInsetLeft = 0;
self.myCategoryView.contentEdgeInsetRight = 0;
self.myCategoryView.cellSpacing = 4;
self.myCategoryView.imageSize = CGSizeMake(160, JXheightForHeaderInSection);
// JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
// lineView.indicatorWidth = 20;
@@ -84,7 +106,7 @@ static const CGFloat JXheightForHeaderInSection = 39;
self.automaticallyAdjustsScrollViewInsets = NO;
CGFloat naviHeight = KB_NAV_TOTAL_HEIGHT;
self.pagerView.pinSectionHeaderVerticalOffset = naviHeight;
self.pagerView.pinSectionHeaderVerticalOffset = naviHeight + 16;
self.naviBGView = [[UIView alloc] init];
self.naviBGView.alpha = 0;
@@ -93,7 +115,7 @@ static const CGFloat JXheightForHeaderInSection = 39;
[self.view addSubview:self.naviBGView];
UILabel *naviTitleLabel = [[UILabel alloc] init];
naviTitleLabel.text = @"导航栏隐藏";
naviTitleLabel.text = KBLocalized(@"Member recharge");
naviTitleLabel.textAlignment = NSTextAlignmentCenter;
naviTitleLabel.frame = CGRectMake(0, KB_STATUSBAR_HEIGHT, self.view.bounds.size.width, 44);
[self.naviBGView addSubview:naviTitleLabel];
@@ -101,12 +123,22 @@ static const CGFloat JXheightForHeaderInSection = 39;
[self.view addSubview:self.closeButton];
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT - 30);
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT - 40);
make.left.equalTo(self.view).offset(15);
make.width.height.mas_equalTo(36);
}];
[self.view addSubview:self.restoreButton];
[self.restoreButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.closeButton);
make.right.equalTo(self.view).offset(-15);
make.width.mas_equalTo(90);
make.height.mas_equalTo(32);
}];
self.pagerView.mainTableView.backgroundColor = [UIColor colorWithHex:0xF6F7FB];
}
- (void)viewDidAppear:(BOOL)animated {
@@ -146,7 +178,7 @@ static const CGFloat JXheightForHeaderInSection = 39;
}
- (UIView *)viewForPinSectionHeaderInPagerView:(JXPagerView *)pagerView {
return self.myCategoryView;
return self.categoryContainer;
}
- (NSInteger)numberOfListsInPagerView:(JXPagerView *)pagerView {
@@ -199,6 +231,25 @@ static const CGFloat JXheightForHeaderInSection = 39;
[self.navigationController popViewControllerAnimated:true];
}
- (void)onTapRestoreButton {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_vip_restore_btn"
pageId:@"vip_pay"
elementId:@"restore_btn"
extra:nil
completion:nil];
[KBHUD show];
__weak typeof(self) weakSelf = self;
[[KBStoreKitBridge shared] restorePurchasesWithCompletion:^(BOOL success, NSString * _Nullable message) {
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) self = weakSelf;
(void)self;
[KBHUD dismiss];
NSString *tip = message.length ? message : (success ? KBLocalized(@"Success") : KBLocalized(@"Failed"));
[KBHUD showInfo:tip];
});
}];
}
#pragma mark - lazy
- (UIButton *)closeButton {
if (!_closeButton) {
@@ -208,4 +259,22 @@ static const CGFloat JXheightForHeaderInSection = 39;
}
return _closeButton;
}
- (UIButton *)restoreButton {
if (!_restoreButton) {
_restoreButton = [UIButton buttonWithType:UIButtonTypeCustom];
_restoreButton.backgroundColor = [[UIColor colorWithHex:0xF6F7FB] colorWithAlphaComponent:0.72];
_restoreButton.layer.cornerRadius = 8;
_restoreButton.layer.masksToBounds = YES;
UIImage *icon = [UIImage imageNamed:@"pay_resh_icon"];
[_restoreButton setImage:icon forState:UIControlStateNormal];
[_restoreButton setTitle:KBLocalized(@"Resume Purchase") forState:UIControlStateNormal];
[_restoreButton setTitleColor:[UIColor colorWithHex:0x02BEAC] forState:UIControlStateNormal];
_restoreButton.titleLabel.font = [KBFont medium:10];
_restoreButton.contentEdgeInsets = UIEdgeInsetsMake(0, 12, 0, 12);
_restoreButton.imageEdgeInsets = UIEdgeInsetsMake(0, -4, 0, 4);
_restoreButton.titleEdgeInsets = UIEdgeInsetsMake(0, 6, 0, -6);
[_restoreButton addTarget:self action:@selector(onTapRestoreButton) forControlEvents:UIControlEventTouchUpInside];
}
return _restoreButton;
}
@end

View File

@@ -92,14 +92,14 @@ static NSString * const kKBSvipBenefitHeaderId = @"kKBSvipBenefitHeaderId";
// 使
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")},
@{@"icon": @"pay_ais_icon", @"title": KBLocalized(@"Wireless Sub-ai Dialogue")},
@{@"icon": @"pay_keyboards_icon", @"title": KBLocalized(@"Personalized Keyboard")},
@{@"icon": @"pay_person_icon", @"title": KBLocalized(@"Chat Persona")},
@{@"icon": @"pay_phone_icon", @"title": KBLocalized(@"Emotional Counseling")},
@{@"icon": @"pay_history_icon", @"title": KBLocalized(@"Longer Chat History")},
@{@"icon": @"pay_chats_icon", @"title": KBLocalized(@"Unlimited Chatting")},
@{@"icon": @"pay_speed_icon", @"title": KBLocalized(@"Chat Without Speed Limits")},
@{@"icon": @"pay_soon_icon", @"title": KBLocalized(@"Coming Soon")},
];
}

View File

@@ -25,7 +25,6 @@ static NSString * const kKBVipReviewListCellId = @"kKBVipReviewListCellId";
@property (nonatomic, strong) UICollectionView *collectionView; //
@property (nonatomic, strong) NSArray<KBPayProductModel *> *plans; //
@property (nonatomic, assign) NSInteger selectedIndex; //
@property (nonatomic, strong) UIButton *restoreButton;
@property (nonatomic, strong) UIImageView *bgImageView; //
// Header
@property (nonatomic, strong) KBVipPayHeaderView *sizingHeader;
@@ -92,12 +91,6 @@ static NSString * const kKBVipReviewListCellId = @"kKBVipReviewListCellId";
make.bottom.equalTo(self.payButton.mas_top).offset(-16);
}];
[self.view addSubview:self.restoreButton];
[self.restoreButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT - 30); make.right.equalTo(self.view).offset(-15);
make.width.mas_equalTo(123);
make.height.mas_equalTo(32);
}];
// Header
self.headerHeight = [self kb_calcHeaderHeightForWidth:KB_SCREEN_WIDTH];
@@ -334,24 +327,7 @@ static NSString * const kKBVipReviewListCellId = @"kKBVipReviewListCellId";
[KBHUD showInfo:KBLocalized(@"Open agreement")];
}
- (void)onTapRestoreButton {
[[KBMaiPointReporter sharedReporter] reportClickWithEventName:@"click_vip_restore_btn"
pageId:@"vip_pay"
elementId:@"restore_btn"
extra:nil
completion:nil];
[KBHUD show];
__weak typeof(self) weakSelf = self;
[[KBStoreKitBridge shared] restorePurchasesWithCompletion:^(BOOL success, NSString * _Nullable message) {
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(weakSelf) self = weakSelf;
(void)self;
[KBHUD dismiss];
NSString *tip = message.length ? message : (success ? KBLocalized(@"Success") : KBLocalized(@"Failed"));
[KBHUD showInfo:tip];
});
}];
}
#pragma mark - UICollectionView DataSource
@@ -492,24 +468,7 @@ static NSString * const kKBVipReviewListCellId = @"kKBVipReviewListCellId";
- (UIButton *)restoreButton {
if (!_restoreButton) {
_restoreButton = [UIButton buttonWithType:UIButtonTypeCustom];
_restoreButton.backgroundColor = [[UIColor colorWithHex:0xF6F7FB] colorWithAlphaComponent:0.72];
_restoreButton.layer.cornerRadius = 8;
_restoreButton.layer.masksToBounds = YES;
UIImage *icon = [UIImage imageNamed:@"pay_resh_icon"];
[_restoreButton setImage:icon forState:UIControlStateNormal];
[_restoreButton setTitle:KBLocalized(@"Resume Purchase") forState:UIControlStateNormal];
[_restoreButton setTitleColor:[UIColor colorWithHex:0x02BEAC] forState:UIControlStateNormal];
_restoreButton.titleLabel.font = [KBFont medium:10];
_restoreButton.contentEdgeInsets = UIEdgeInsetsMake(0, 12, 0, 12);
_restoreButton.imageEdgeInsets = UIEdgeInsetsMake(0, -4, 0, 4);
_restoreButton.titleEdgeInsets = UIEdgeInsetsMake(0, 6, 0, -6);
[_restoreButton addTarget:self action:@selector(onTapRestoreButton) forControlEvents:UIControlEventTouchUpInside];
}
return _restoreButton;
}
- (UIButton *)payButton {
if (!_payButton) {