This commit is contained in:
2025-12-11 13:16:06 +08:00
parent e39104c431
commit d348b35984
12 changed files with 387 additions and 52 deletions

View File

@@ -11,9 +11,12 @@
#import "KBSkinCardCell.h"
#import "KBSkinInstallBridge.h"
#import "KBHUD.h"
#import "KBShopVM.h"
@interface KBShopItemVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
@property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
@property (nonatomic, strong) KBShopVM *internalViewModel;
@property (nonatomic, assign, getter=isLoading) BOOL loading;
@end
@implementation KBShopItemVC
@@ -21,6 +24,7 @@
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor clearColor];
self.dataSource = [NSMutableArray array];
// collectionView
[self.view addSubview:self.collectionView];
@@ -28,26 +32,19 @@
make.edges.equalTo(self.view); // mas
}];
// 2
KBWeakSelf
if (self.isNeedHeader) {
self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf.collectionView.mj_header endRefreshing];
});
[weakSelf fetchThemes];
}];
}
if (self.isNeedFooter) {
self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf.dataSource addObject:KBLocalized(@"Loaded more successfully")]; //
[weakSelf.collectionView reloadData];
[weakSelf.collectionView.mj_footer endRefreshing];
});
[weakSelf fetchThemes];
}];
}
self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
[self beginFirstRefresh];
}
@@ -56,23 +53,58 @@
//
- (void)beginFirstRefresh {
if (!self.isHeaderRefreshed) {
[self beginRefreshImmediately];
if (self.isHeaderRefreshed || self.isLoading) {
return;
}
if (!self.style.styleId.length) {
return;
}
[self beginRefreshImmediately];
}
- (void)beginRefreshImmediately {
if (self.isNeedHeader) {
if (self.isNeedHeader && !self.collectionView.mj_header.isRefreshing) {
[self.collectionView.mj_header beginRefreshing];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.isHeaderRefreshed = YES;
[self.collectionView reloadData];
[self.collectionView.mj_header endRefreshing];
});
} else {
self.isHeaderRefreshed = YES;
[self.collectionView reloadData];
}
[self fetchThemes];
}
- (void)fetchThemes {
if (self.isLoading) {
return;
}
NSString *styleId = self.style.styleId;
if (!styleId.length) {
return;
}
self.loading = YES;
KBShopVM *vm = self.shopViewModel;
if (!vm) {
if (!self.internalViewModel) {
self.internalViewModel = [[KBShopVM alloc] init];
}
vm = self.internalViewModel;
}
KBWeakSelf
[vm fetchThemesForStyleId:styleId completion:^(NSArray<KBShopThemeModel *> * _Nullable themes, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.loading = NO;
weakSelf.isHeaderRefreshed = YES;
if (error) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"Network error");
[KBHUD showInfo:msg];
} else {
weakSelf.dataSource = themes.count ? themes.mutableCopy : [NSMutableArray array];
[weakSelf.collectionView reloadData];
}
if ([weakSelf.collectionView.mj_header isRefreshing]) {
[weakSelf.collectionView.mj_header endRefreshing];
}
if ([weakSelf.collectionView.mj_footer isRefreshing]) {
[weakSelf.collectionView.mj_footer endRefreshing];
}
});
}];
}
#pragma mark - UICollectionView DataSource
@@ -84,8 +116,10 @@
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
KBSkinCardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"KBSkinCardCell" forIndexPath:indexPath];
NSString *title = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : @"Dopamine";
[cell configWithTitle:title imageURL:nil price:@"20"]; // 20
KBShopThemeModel *theme = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : nil;
NSString *title = theme.themeName.length ? theme.themeName : KBLocalized(@"Themes");
NSString *price = [self kb_priceStringForTheme:theme];
[cell configWithTitle:title imageURL:nil price:price];
return cell;
}
@@ -117,8 +151,28 @@
[self kb_handleShopTapAtIndexPath:indexPath];
}
- (NSString *)kb_priceStringForTheme:(KBShopThemeModel *)theme {
if (!theme) {
return @"";
}
if (theme.themePrice <= 0.0f) {
return KBLocalized(@"Free");
}
static NSNumberFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [[NSNumberFormatter alloc] init];
formatter.minimumFractionDigits = 0;
formatter.maximumFractionDigits = 2;
formatter.minimumIntegerDigits = 1;
});
NSString *priceString = [formatter stringFromNumber:@(theme.themePrice)];
return priceString ?: [NSString stringWithFormat:@"%.2f", theme.themePrice];
}
- (void)kb_handleShopTapAtIndexPath:(NSIndexPath *)indexPath {
NSString *title = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : KBLocalized(@"专属皮肤002");
KBShopThemeModel *theme = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : nil;
NSString *title = theme.themeName.length ? theme.themeName : KBLocalized(@"专属皮肤002");
// 002.zip id便
static NSString * const kKBBundleSkinId002 = @"bundle_skin_fense";
[KBSkinInstallBridge publishBundleSkinRequestWithId:kKBBundleSkinId002
@@ -128,6 +182,13 @@
[KBHUD showInfo:KBLocalized(@"已通知键盘解压,切换到自定义键盘即可生效")];
}
- (void)setStyle:(KBShopStyleModel *)style {
_style = style;
if (self.isViewLoaded && !self.isHeaderRefreshed) {
[self beginFirstRefresh];
}
}
#pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
!self.scrollCallback ?: self.scrollCallback(scrollView);