This commit is contained in:
2025-11-13 16:23:46 +08:00
parent f406416698
commit a61b5fa2fd
6 changed files with 276 additions and 18 deletions

View File

@@ -96,7 +96,12 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
return path;
}
if (self.baseURL) {
return [NSURL URLWithString:path relativeToURL:self.baseURL].absoluteURL.absoluteString;
// base / path / base
NSString *base = self.baseURL.absoluteString ?: @"";
if (![base hasSuffix:@"/"]) { base = [base stringByAppendingString:@"/"]; }
NSURL *dirBase = [NSURL URLWithString:base];
NSString *relative = ([path hasPrefix:@"/"]) ? [path substringFromIndex:1] : path;
return [NSURL URLWithString:relative relativeToURL:dirBase].absoluteURL.absoluteString;
}
return path; // baseURL path URL AFN
}

View File

@@ -176,13 +176,6 @@ static NSString * const kKBKeyboardExtensionBundleId = @"com.loveKey.nyx.CustomK
NSDictionary *params = @{
@"code": tokenString ?: @"",
};
// [[KBNetworkManager shared] POST:@"/user/appleLogin" parameters:params headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
//
// } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//
// } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//
// }];
[[KBNetworkManager shared] POST:@"/user/appleLogin" jsonBody:params headers:nil completion:^(id _Nullable jsonOrData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"=====");
}];

View File

@@ -122,7 +122,13 @@ NSErrorDomain const KBNetworkErrorDomain = @"com.company.keyboard.network";
return path;
}
if (self.baseURL) {
return [NSURL URLWithString:path relativeToURL:self.baseURL].absoluteURL.absoluteString;
// 1) base /
NSString *base = self.baseURL.absoluteString ?: @"";
if (![base hasSuffix:@"/"]) { base = [base stringByAppendingString:@"/"]; }
NSURL *dirBase = [NSURL URLWithString:base];
// 2) / path /api
NSString *relative = ([path hasPrefix:@"/"]) ? [path substringFromIndex:1] : path;
return [NSURL URLWithString:relative relativeToURL:dirBase].absoluteURL.absoluteString;
}
return path; // baseURL path URL AFN
}

View File

@@ -9,8 +9,18 @@
NS_ASSUME_NONNULL_BEGIN
/// 商城顶部头图
/// 还原设计稿见需求截图左侧「Points\nMall」标题 + 右侧大金币装饰
/// 下方卡片显示积分与「Recharge」按钮。
/// Masonry 约束 + 懒加载,中文注释。
@interface KBShopHeadView : UIView
/// 点击充值回调
@property (nonatomic, copy) void (^onRechargeTapped)(void);
/// 更新积分展示
- (void)updatePoints:(NSString *)points;
@end
NS_ASSUME_NONNULL_END

View File

@@ -6,16 +6,260 @@
//
#import "KBShopHeadView.h"
@interface KBShopHeadView()
@interface KBShopHeadView ()
//
@property (nonatomic, strong) UIView *containerView;
//
@property (nonatomic, strong) UILabel *titleLabel; // "Points\nMall"
@property (nonatomic, strong) UIImageView *yellowStarView; // shop_yellowxx_icon
@property (nonatomic, strong) UIImageView *greenStarView; // 绿shop_greenxx_icon
//
@property (nonatomic, strong) UIImageView *bigCoinView; // shop_headbigBg_icon
//
@property (nonatomic, strong) UIView *infoCard; // 绿
@property (nonatomic, strong) UILabel *myPointsLabel; // "My Points"
@property (nonatomic, strong) UIImageView *smallCoinView; // shop_jb_icon
@property (nonatomic, strong) UILabel *amountLabel; // 88.00
@property (nonatomic, strong) UIButton *rechargeButton; // recharge_btn_bg
@end
@implementation KBShopHeadView
- (instancetype)initWithFrame:(CGRect)frame{
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor clearColor];
//
[self addSubview:self.containerView];
[self.containerView addSubview:self.titleLabel];
[self.containerView addSubview:self.yellowStarView];
[self.containerView addSubview:self.greenStarView];
[self.containerView addSubview:self.bigCoinView];
[self.containerView addSubview:self.infoCard];
[self.infoCard addSubview:self.myPointsLabel];
[self.infoCard addSubview:self.smallCoinView];
[self.infoCard addSubview:self.amountLabel];
[self.infoCard addSubview:self.rechargeButton];
//
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(16);
make.right.equalTo(self).offset(-16);
make.top.equalTo(self);
make.bottom.equalTo(self);
}];
//
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.left.equalTo(self.containerView).offset(0);
make.bottom.equalTo(self.containerView).offset(0);
}];
//
[self.yellowStarView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.titleLabel.mas_centerY).offset(6);
make.left.equalTo(self.containerView).offset(6);
make.width.height.mas_equalTo(16);
}];
// 绿
[self.greenStarView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.containerView).offset(10);
make.right.equalTo(self.containerView).offset(-6);
make.width.height.mas_equalTo(14);
}];
//
[self.bigCoinView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom.equalTo(self.containerView);
make.left.right.equalTo(self.containerView);
make.height.mas_equalTo(KBFit(238));
}];
//
[self.infoCard mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.containerView);
make.bottom.equalTo(self.containerView);
make.height.mas_equalTo(KBFit(140));
}];
[self.myPointsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.infoCard).offset(16);
make.top.equalTo(self.infoCard).offset(16);
}];
[self.smallCoinView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.infoCard).offset(16);
make.top.equalTo(self.myPointsLabel.mas_bottom).offset(12);
make.width.height.mas_equalTo(36);
}];
[self.amountLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.smallCoinView.mas_right).offset(10);
make.centerY.equalTo(self.smallCoinView);
}];
[self.rechargeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.equalTo(self.amountLabel);
make.right.equalTo(self.infoCard).offset(-16);
make.width.mas_equalTo(120);
make.height.mas_equalTo(40);
}];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
//
// self.containerView.layer.cornerRadius = 16.0;
// self.containerView.layer.masksToBounds = YES;
//
// self.infoCard.layer.cornerRadius = 16.0;
// self.infoCard.layer.masksToBounds = YES;
//
// // 绿
// //
// NSMutableArray<CALayer *> *remove = [NSMutableArray array];
// for (CALayer *l in self.infoCard.layer.sublayers) {
// if ([l isKindOfClass:[CAGradientLayer class]]) { [remove addObject:l]; }
// }
// for (CALayer *l in remove) { [l removeFromSuperlayer]; }
//
// CAGradientLayer *g = [CAGradientLayer layer];
// g.colors = @[(__bridge id)[UIColor colorWithHex:0xF4FFFE].CGColor,
// (__bridge id)[UIColor colorWithHex:0xE8FFF6].CGColor];
// g.startPoint = CGPointMake(0, 0.5);
// g.endPoint = CGPointMake(1, 0.5);
// g.frame = self.infoCard.bounds;
// [self.infoCard.layer insertSublayer:g atIndex:0];
}
#pragma mark - Public
- (void)updatePoints:(NSString *)points {
if (points.length == 0) { points = @"0"; }
self.amountLabel.text = points;
}
#pragma mark - Actions
- (void)onRechargeTappedAction {
if (self.onRechargeTapped) { self.onRechargeTapped(); }
}
#pragma mark - Lazy UI
- (UIView *)containerView {
if (!_containerView) {
_containerView = [UIView new];
// _containerView.backgroundColor = [UIColor whiteColor];
}
return _containerView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [UILabel new];
_titleLabel.numberOfLines = 0;
_titleLabel.text = @"Points\nMall"; //
_titleLabel.font = [UIFont systemFontOfSize:30 weight:UIFontWeightBold];
_titleLabel.textColor = [UIColor colorWithHex:0x1B1F1A];
}
return _titleLabel;
}
- (UIImageView *)yellowStarView {
if (!_yellowStarView) {
_yellowStarView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"shop_yellowxx_icon"]];
_yellowStarView.contentMode = UIViewContentModeScaleAspectFit;
}
return _yellowStarView;
}
- (UIImageView *)greenStarView {
if (!_greenStarView) {
_greenStarView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"shop_greenxx_icon"]];
_greenStarView.contentMode = UIViewContentModeScaleAspectFit;
}
return _greenStarView;
}
- (UIImageView *)bigCoinView {
if (!_bigCoinView) {
_bigCoinView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"shop_headbigBg_icon"]];
_bigCoinView.contentMode = UIViewContentModeScaleAspectFit;
}
return _bigCoinView;
}
- (UIView *)infoCard {
if (!_infoCard) {
_infoCard = [UIView new];
}
return _infoCard;
}
- (UILabel *)myPointsLabel {
if (!_myPointsLabel) {
_myPointsLabel = [UILabel new];
_myPointsLabel.text = @"My Points";
_myPointsLabel.textColor = [UIColor colorWithHex:0x1B1F1A];
_myPointsLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
}
return _myPointsLabel;
}
- (UIImageView *)smallCoinView {
if (!_smallCoinView) {
_smallCoinView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"shop_jb_icon"]];
_smallCoinView.contentMode = UIViewContentModeScaleAspectFit;
}
return _smallCoinView;
}
- (UILabel *)amountLabel {
if (!_amountLabel) {
_amountLabel = [UILabel new];
_amountLabel.text = @"88.00"; //
_amountLabel.textColor = [UIColor colorWithHex:KBColorValue];
_amountLabel.font = [UIFont systemFontOfSize:38 weight:UIFontWeightBold];
_amountLabel.adjustsFontSizeToFitWidth = YES;
_amountLabel.minimumScaleFactor = 0.7;
}
return _amountLabel;
}
- (UIButton *)rechargeButton {
if (!_rechargeButton) {
_rechargeButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_rechargeButton setTitle:@"Recharge" forState:UIControlStateNormal];
[_rechargeButton setTitleColor:[UIColor colorWithHex:0x1B1F1A] forState:UIControlStateNormal];
_rechargeButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
//
UIImage *bg = [UIImage imageNamed:@"recharge_btn_bg"];
if (bg) {
CGFloat cap = 20; //
bg = [bg resizableImageWithCapInsets:UIEdgeInsetsMake(cap, cap, cap, cap) resizingMode:UIImageResizingModeStretch];
[_rechargeButton setBackgroundImage:bg forState:UIControlStateNormal];
} else {
// 绿
UIImage *fallback = [UIImage kb_gradientImageWithColors:@[[UIColor colorWithHex:0xA6F6E9], [UIColor colorWithHex:0xD6FFF4]]
size:CGSizeMake(120, 40)
direction:KBGradientDirectionLeftToRight];
[_rechargeButton setBackgroundImage:fallback forState:UIControlStateNormal];
}
_rechargeButton.layer.cornerRadius = 20;
_rechargeButton.layer.masksToBounds = YES;
[_rechargeButton addTarget:self action:@selector(onRechargeTappedAction) forControlEvents:UIControlEventTouchUpInside];
}
return _rechargeButton;
}
@end

View File

@@ -143,7 +143,7 @@ static const CGFloat JXheightForHeaderInSection = 50;
self.naviBGView = [[UIView alloc] init];
self.naviBGView.alpha = 0;
self.naviBGView.backgroundColor = [UIColor whiteColor];
self.naviBGView.backgroundColor = [UIColor clearColor];
self.naviBGView.frame = CGRectMake(0, 0, KB_SCREEN_WIDTH, KB_NAV_TOTAL_HEIGHT);
[self.view addSubview:self.naviBGView];
UILabel *naviTitleLabel = [[UILabel alloc] init];
@@ -219,15 +219,15 @@ static const CGFloat JXheightForHeaderInSection = 50;
- (void)pagerView:(JXPagerView *)pagerView mainTableViewDidScroll:(UIScrollView *)scrollView {
// -
// -
CGFloat headerH = (CGFloat)[self tableHeaderViewHeightInPagerView:self.pagerView];
CGFloat thresholdDistance = MAX(0.0, headerH - self.pagerView.pinSectionHeaderVerticalOffset);
CGFloat percent = (thresholdDistance > 0 ? scrollView.contentOffset.y/thresholdDistance : 1);
percent = MAX(0, MIN(1, percent));
self.naviBGView.alpha = percent;
//
// -
// alpha=0() alpha=1
BOOL shouldWhite = (thresholdDistance > 0.0 && scrollView.contentOffset.y >= (thresholdDistance - 0.5));
self.naviBGView.alpha = shouldWhite ? 1.0 : 0.0;
//
if (shouldWhite != self.categoryIsWhite) {
self.categoryIsWhite = shouldWhite;
UIColor *bg = shouldWhite ? [UIColor whiteColor] : [UIColor clearColor];