// // HomeRankContentVC.m // keyBoard // // Created by Mac on 2025/11/6. // @import UIKit; #import "HomeRankContentVC.h" #import "HomeRankDetailPopView.h" // 自定义弹窗内容视图 #import "LSTPopView.h" // LSTPopView 弹窗框架 // 自定义卡片 Cell #import "HomeRankCardCell.h" #import "KBHomeVM.h" #import "KBCharacter.h" #import "KBHUD.h" #import "KBMyVM.h" // 引入用户人设变更通知 @interface HomeRankContentVC () @property (nonatomic, copy, nullable) NSString *tagId; // 当前标签 id @property (nonatomic, strong) KBHomeVM *homeVM; @property (nonatomic, strong) NSArray *characters; // 当前标签下的角色列表 @end @implementation HomeRankContentVC - (instancetype)initWithTagId:(NSString *)tagId { if (self = [super init]) { _tagId = [tagId copy]; } return self; } - (instancetype)init { return [self initWithTagId:nil]; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = COLOR_WITH_RGB(246/255.0, 253/255.0, 249/255.0, 1.0); // 淡绿色背景 self.characters = @[]; self.homeVM = [KBHomeVM new]; [self.view addSubview:self.collectionView]; [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; // 监听“用户人设删除”通知,用于同步更新加号按钮状态 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(kb_onUserCharacterDeleted:) name:KBUserCharacterDeletedNotification object:nil]; // 加载当前 tag 下的角色列表 [self loadCharactersForCurrentTag]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)loadCharactersForCurrentTag { [self kb_requestCharactersWithShowHUD:YES]; } // 内部通用方法:根据 tag 请求角色列表 - (void)kb_requestCharactersWithShowHUD:(BOOL)needShow { KBWeakSelf [self.homeVM fetchRankListByTagId:self.tagId needShow:needShow completion:^(NSArray * _Nullable list, NSError * _Nullable error) { if (error) { return; } weakSelf.characters = list ?: @[]; [weakSelf.collectionView reloadData]; }]; } /// 收到“用户人设删除”通知:如果当前列表包含该 id,则刷新接口数据 - (void)kb_onUserCharacterDeleted:(NSNotification *)note { NSNumber *cid = note.userInfo[@"characterId"]; if (!cid) { return; } NSInteger targetId = cid.integerValue; if (targetId <= 0) { return; } BOOL contains = NO; for (KBCharacter *c in self.characters) { if (c.ID.integerValue == targetId) { contains = YES; break; } } if (!contains) { return; } // 后端会根据最新的人设状态返回 added 字段,刷新本页 UI [self kb_requestCharactersWithShowHUD:NO]; } - (UICollectionView *)collectionView{ if (!_collectionView) { UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init]; layout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16); layout.minimumLineSpacing = 24; layout.minimumInteritemSpacing = 16; _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout]; _collectionView.backgroundColor = [UIColor clearColor]; // _collectionView.alwaysBounceVertical = YES; _collectionView.bounces = false; _collectionView.dataSource = self; _collectionView.delegate = self; [_collectionView registerClass:[HomeRankCardCell class] forCellWithReuseIdentifier:@"HomeRankCardCell"]; // self.collectionView.translatesAutoresizingMaskIntoConstraints = NO; } return _collectionView; } #pragma mark - UICollectionViewDataSource - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.characters.count; } - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { HomeRankCardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"HomeRankCardCell" forIndexPath:indexPath]; KBCharacter *c = self.characters[indexPath.item]; // 直接把模型交给 cell,由 cell 自己负责展示 cell.character = c; KBWeakSelf cell.onTapAction = ^{ // 切换添加/已添加状态并刷新该项(只是本地 UI 状态) NSMutableArray *m = [weakSelf.characters mutableCopy]; KBCharacter *mc = m[indexPath.item]; mc.added = !mc.added; weakSelf.characters = [m copy]; [weakSelf.collectionView reloadItemsAtIndexPaths:@[indexPath]]; }; return cell; } #pragma mark - UICollectionViewDelegateFlowLayout - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { CGFloat totalHInset = 16 + 16; CGFloat spacing = 16; CGFloat w = collectionView.bounds.size.width - totalHInset; CGFloat cellWidth = (w - spacing) / 2.0; // 固定高度,接近示意图比例 CGFloat cellHeight = 234.0; return CGSizeMake(floor(cellWidth), cellHeight); } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ // 点击卡片 -> 展示弹窗 KBCharacter *c = self.characters[indexPath.item]; // 自定义内容视图(尺寸可按需调节) CGFloat width = MIN(KB_SCREEN_WIDTH - 76, 420); HomeRankDetailPopView *content = [[HomeRankDetailPopView alloc] initWithFrame:CGRectMake(0, 0, width, 460)]; NSString *title = c.characterName ?: @"High EQ"; NSString *people = c.download ?: @"Download: 1 Million"; NSString *desc = @"Be Neither Too Close\nNor Too Distant"; // 示例文案 [content configWithAvatar:nil title:title download:people desc:desc]; // 创建并弹出 LSTPopView *pop = [LSTPopView initWithCustomView:content parentView:nil popStyle:LSTPopStyleScale dismissStyle:LSTDismissStyleScale]; pop.hemStyle = LSTHemStyleCenter; // 居中 pop.bgColor = [[UIColor blackColor] colorWithAlphaComponent:0.4]; pop.isClickBgDismiss = YES; // 点击背景关闭 pop.cornerRadius = 0; // 自定义 view 自处理圆角 __weak typeof(pop) weakPop = pop; content.saveHandler = ^{ [weakPop dismiss]; }; content.closeHandler = ^{ [weakPop dismiss]; }; [pop pop]; } #pragma mark - JXCategoryListContentViewDelegate - (UIView *)listView { return self.view; } @end