Files
keyboard/keyBoard/Class/Shop/VC/KBShopItemVC.m

222 lines
8.4 KiB
Mathematica
Raw Normal View History

2025-11-09 13:56:13 +08:00
//
// KBShopItemVC.m
// keyBoard
//
// Created by Mac on 2025/11/9.
//
#import "KBShopItemVC.h"
#import <MJRefresh/MJRefresh.h>
2025-11-09 18:07:47 +08:00
#import <Masonry/Masonry.h>
#import "KBSkinCardCell.h"
2025-11-20 14:27:57 +08:00
#import "KBSkinInstallBridge.h"
#import "KBHUD.h"
2025-12-11 13:16:06 +08:00
#import "KBShopVM.h"
2025-11-09 13:56:13 +08:00
2025-11-09 18:07:47 +08:00
@interface KBShopItemVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
2025-11-09 13:56:13 +08:00
@property (nonatomic, copy) void(^scrollCallback)(UIScrollView *scrollView);
2025-12-11 13:16:06 +08:00
@property (nonatomic, strong) KBShopVM *internalViewModel;
@property (nonatomic, assign, getter=isLoading) BOOL loading;
2025-11-09 13:56:13 +08:00
@end
@implementation KBShopItemVC
- (void)viewDidLoad {
[super viewDidLoad];
2025-11-13 15:34:56 +08:00
self.view.backgroundColor = [UIColor clearColor];
2025-12-11 13:16:06 +08:00
self.dataSource = [NSMutableArray array];
2025-11-09 13:56:13 +08:00
2025-11-09 18:07:47 +08:00
// collectionView
[self.view addSubview:self.collectionView];
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view); // mas
}];
2025-11-09 13:56:13 +08:00
2025-11-10 15:38:30 +08:00
KBWeakSelf
2025-11-09 13:56:13 +08:00
if (self.isNeedHeader) {
2025-11-09 18:07:47 +08:00
self.collectionView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
2025-12-11 13:16:06 +08:00
[weakSelf fetchThemes];
2025-11-09 13:56:13 +08:00
}];
}
if (self.isNeedFooter) {
2025-11-09 18:07:47 +08:00
self.collectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
2025-12-11 13:16:06 +08:00
[weakSelf fetchThemes];
2025-11-09 13:56:13 +08:00
}];
2025-11-09 18:07:47 +08:00
}
2025-12-11 13:16:06 +08:00
self.collectionView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
2025-11-09 13:56:13 +08:00
[self beginFirstRefresh];
}
2025-11-09 18:07:47 +08:00
#pragma mark -
2025-11-09 13:56:13 +08:00
2025-11-09 18:07:47 +08:00
//
2025-11-09 13:56:13 +08:00
- (void)beginFirstRefresh {
2025-12-11 13:16:06 +08:00
if (self.isHeaderRefreshed || self.isLoading) {
return;
2025-11-09 13:56:13 +08:00
}
2025-12-11 13:16:06 +08:00
if (!self.style.styleId.length) {
return;
}
[self beginRefreshImmediately];
2025-11-09 13:56:13 +08:00
}
- (void)beginRefreshImmediately {
2025-12-11 13:16:06 +08:00
if (self.isNeedHeader && !self.collectionView.mj_header.isRefreshing) {
2025-11-09 18:07:47 +08:00
[self.collectionView.mj_header beginRefreshing];
2025-11-09 13:56:13 +08:00
}
2025-12-11 13:16:06 +08:00
[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];
}
});
}];
2025-11-09 13:56:13 +08:00
}
2025-11-09 18:07:47 +08:00
#pragma mark - UICollectionView DataSource
2025-11-09 13:56:13 +08:00
2025-11-09 18:07:47 +08:00
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (!self.isHeaderRefreshed) return 0;
2025-11-09 13:56:13 +08:00
return self.dataSource.count;
}
2025-11-09 18:07:47 +08:00
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
KBSkinCardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"KBSkinCardCell" forIndexPath:indexPath];
2025-12-11 13:16:06 +08:00
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];
2025-11-09 13:56:13 +08:00
return cell;
}
2025-11-09 18:07:47 +08:00
#pragma mark - UICollectionView DelegateFlowLayout
2025-11-09 13:56:13 +08:00
2025-11-09 18:07:47 +08:00
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// 16 12
CGFloat insetLR = 16.0;
CGFloat spacing = 12.0;
CGFloat contentW = collectionView.bounds.size.width - insetLR * 2;
CGFloat itemW = floor((contentW - spacing) / 2.0);
2025-11-17 14:53:23 +08:00
// CGFloat itemH = itemW * 0.75 + 56; // KBSkinCardCell
return CGSizeMake(itemW, KBFit(197));
2025-11-09 13:56:13 +08:00
}
2025-11-09 18:07:47 +08:00
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(12, 16, 12, 16);
2025-11-09 13:56:13 +08:00
}
2025-11-09 18:07:47 +08:00
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 12.0;
2025-11-09 13:56:13 +08:00
}
2025-11-09 18:07:47 +08:00
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 12.0;
2025-11-09 13:56:13 +08:00
}
2025-11-20 14:27:57 +08:00
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
[self kb_handleShopTapAtIndexPath:indexPath];
}
2025-12-11 13:16:06 +08:00
- (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];
}
2025-11-20 14:27:57 +08:00
- (void)kb_handleShopTapAtIndexPath:(NSIndexPath *)indexPath {
2025-12-11 13:16:06 +08:00
KBShopThemeModel *theme = (indexPath.item < self.dataSource.count) ? self.dataSource[indexPath.item] : nil;
NSString *title = theme.themeName.length ? theme.themeName : KBLocalized(@"专属皮肤002");
2025-11-20 14:27:57 +08:00
// 002.zip id便
2025-11-20 18:23:56 +08:00
static NSString * const kKBBundleSkinId002 = @"bundle_skin_fense";
2025-11-20 14:27:57 +08:00
[KBSkinInstallBridge publishBundleSkinRequestWithId:kKBBundleSkinId002
name:title ?: kKBBundleSkinId002
2025-11-20 18:23:56 +08:00
zipName:@"fense.zip"
2025-11-20 14:27:57 +08:00
iconShortNames:nil];
[KBHUD showInfo:KBLocalized(@"已通知键盘解压,切换到自定义键盘即可生效")];
}
2025-12-11 13:16:06 +08:00
- (void)setStyle:(KBShopStyleModel *)style {
_style = style;
if (self.isViewLoaded && !self.isHeaderRefreshed) {
[self beginFirstRefresh];
}
}
2025-11-09 18:07:47 +08:00
#pragma mark - UIScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
!self.scrollCallback ?: self.scrollCallback(scrollView);
2025-11-09 13:56:13 +08:00
}
2025-11-09 18:07:47 +08:00
#pragma mark - JXPagingViewListViewDelegate
- (UIView *)listView { return self.view; }
- (UIScrollView *)listScrollView { return self.collectionView; }
- (void)listViewDidScrollCallback:(void (^)(UIScrollView *))callback { self.scrollCallback = callback; }
- (void)listWillAppear { NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); }
- (void)listDidAppear { NSLog(@"%@:%@", self.title, NSStringFromSelector(_cmd)); }
- (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];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
2025-11-13 15:34:56 +08:00
_collectionView.backgroundColor = [UIColor clearColor];
2025-11-09 18:07:47 +08:00
_collectionView.dataSource = self;
_collectionView.delegate = self;
// cell
[_collectionView registerClass:KBSkinCardCell.class forCellWithReuseIdentifier:@"KBSkinCardCell"]; //
}
return _collectionView;
2025-11-09 13:56:13 +08:00
}
@end