Files
keyboard/keyBoard/Class/Home/VC/HomeHotVC.m
2025-12-08 16:39:47 +08:00

306 lines
11 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HomeHotVC.m
// keyBoard
//
// Created by Mac on 2025/11/6.
//
#import "HomeHotVC.h"
// 视图
#import "KBTopThreeView.h"
#import "KBHomeVM.h"
#import "KBCharacter.h"
#import "HomeHotCell.h"
#import "HomeRankVC.h"
#import "KBSearchVC.h"
#import "HomeRankDetailPopView.h"
#import "LSTPopView.h"
#import <HWPanModal/HWPanModal.h>
#import "KBMyVM.h" // 用户人设变更通知
#import "KBHUD.h"
@interface HomeHotVC () <UITableViewDataSource, UITableViewDelegate>
// 顶部前三名视图
@property (nonatomic, strong) KBTopThreeView *topThreeView;
/// 首页排行榜 VM
@property (nonatomic, strong) KBHomeVM *homeVM;
/// 完整的排行榜数据(接口返回)
@property (nonatomic, copy) NSArray<KBCharacter *> *allCharacters;
/// 列表区域使用的数据:从第 4 名开始
@property (nonatomic, copy) NSArray<KBCharacter *> *listCharacters;
@end
@interface HomeHotVC ()
@end
@implementation HomeHotVC
- (void)viewDidLoad {
[super viewDidLoad];
// 搭建 UI
[self.view addSubview:self.tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
// 顶部前三名作为 tableHeaderView注意tableHeaderView 需设定明确高度)
CGFloat headerH = 280.0;
self.topThreeView = [[KBTopThreeView alloc] initWithFrame:CGRectMake(0, 0, KB_SCREEN_WIDTH, headerH)];
self.tableView.tableHeaderView = self.topThreeView;
KBWeakSelf
// 顶部三名区域的三个加号按钮:添加人设
self.topThreeView.onCenterPlusTapped = ^(KBCharacter * _Nullable character) {
[weakSelf kb_addUserCharacterFromTopViewWithCharacter:character];
};
self.topThreeView.onLeftPlusTapped = ^(KBCharacter * _Nullable character) {
[weakSelf kb_addUserCharacterFromTopViewWithCharacter:character];
};
self.topThreeView.onRightPlusTapped = ^(KBCharacter * _Nullable character) {
[weakSelf kb_addUserCharacterFromTopViewWithCharacter:character];
};
// 请求排行榜数据
self.homeVM = [KBHomeVM new];
[self kb_reloadRankListWithShowHUD:YES];
// 监听“用户人设删除”通知,用于同步更新加号按钮状态
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(kb_onUserCharacterDeleted:)
name:KBUserCharacterDeletedNotification
object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
/// 拉取首页排行榜数据
- (void)kb_reloadRankListWithShowHUD:(BOOL)needShow {
KBWeakSelf
[self.homeVM fetchRankListWithParams:nil
needShow:needShow
completion:^(NSArray<KBCharacter *> * _Nullable list, NSError * _Nullable error) {
if (error) {
// 错误提示已经在 VM 内部通过 HUD 处理,这里不再重复提示
return;
}
weakSelf.allCharacters = list ?: @[];
// 根据最新数据刷新顶部前三名与列表部分
[weakSelf kb_refreshTopThreeView];
[weakSelf kb_refreshListCharacters];
[weakSelf.tableView reloadData];
// 通知承载 HomeHotVC 的“外层 PanModal 容器”刷新布局。
// 1) 如果 HomeHotVC 是作为子控制器嵌在某个 VC 里(例如 HomeSheetVC
// 则该 VC 实现了 hw_panModalSetNeedsLayoutUpdate。
UIViewController *parent = weakSelf.parentViewController;
id target = nil;
if ([parent respondsToSelector:@selector(hw_panModalSetNeedsLayoutUpdate)]) {
target = parent;
} else {
// 2) 如果 HomeHotVC 是直接嵌在 HWPanModalContentView如 KBPanModalView
// parentViewController 可能为 nil需要顺着 view.superview 向上寻找。
UIView *v = weakSelf.view;
while (v && ![v respondsToSelector:@selector(hw_panModalSetNeedsLayoutUpdate)]) {
v = v.superview;
}
if (v && [v respondsToSelector:@selector(hw_panModalSetNeedsLayoutUpdate)]) {
target = v;
}
}
if (target) {
[(id)target hw_panModalSetNeedsLayoutUpdate];
}
}];
}
/// 收到“用户人设删除”通知:如果当前列表包含该 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.allCharacters) {
if (c.ID.integerValue == targetId) {
contains = YES;
break;
}
}
if (!contains) { return; }
// 刷新首页排行榜数据(不需要 HUD
[self kb_reloadRankListWithShowHUD:NO];
}
/// 根据当前 allCharacters 刷新顶部前三名区域
- (void)kb_refreshTopThreeView {
NSInteger topCount = MIN(3, self.allCharacters.count);
if (topCount > 0) {
NSRange range = NSMakeRange(0, topCount);
NSArray<KBCharacter *> *topThree = [self.allCharacters subarrayWithRange:range];
[self.topThreeView configWithCharacters:topThree];
} else {
[self.topThreeView configWithCharacters:@[]];
}
}
/// 根据当前 allCharacters 刷新列表区域(第 4 名及以后)
- (void)kb_refreshListCharacters {
if (self.allCharacters.count > 3) {
NSRange range = NSMakeRange(3, self.allCharacters.count - 3);
self.listCharacters = [self.allCharacters subarrayWithRange:range];
} else {
self.listCharacters = @[];
}
}
/// 顶部三名区域点击“+”添加人设
- (void)kb_addUserCharacterFromTopViewWithCharacter:(KBCharacter * _Nullable)character {
if (!character || character.added) { return; }
NSString *cidStr = character.ID ?: @"";
if (cidStr.length == 0) { return; }
NSNumber *cid = @([cidStr integerValue]);
NSString *emoji = character.emoji ? character.emoji : @"";
[self.homeVM addUserCharacterWithId:cid emoji : emoji
completion:^(BOOL success, NSError * _Nullable error) {
if (!success) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"Network error");
[KBHUD showInfo:msg];
return;
}
// 添加成功:更新模型状态
character.added = YES;
// 刷新顶部与列表 UI
[self kb_refreshTopThreeView];
[self.tableView reloadData];
}];
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.listCharacters.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HomeHotCell *cell = [tableView dequeueReusableCellWithIdentifier:HomeHotCell.reuseId forIndexPath:indexPath];
KBCharacter *item = self.listCharacters[indexPath.row];
// 直接把模型交给 cell由 cell 自己负责展示
cell.character = item;
KBWeakSelf
__weak typeof(cell) weakCell = cell;
cell.onTapAction = ^{
__strong typeof(weakSelf) self = weakSelf;
HomeHotCell *strongCell = weakCell;
if (!self || !strongCell) { return; }
NSIndexPath *current = [self.tableView indexPathForCell:strongCell];
if (!current) { return; }
if (current.row >= self.listCharacters.count) { return; }
KBCharacter *mc = self.listCharacters[current.row];
// 已添加状态下不允许再次点击
if (mc.added) { return; }
NSString *cidStr = mc.ID ?: @"";
if (cidStr.length == 0) { return; }
NSNumber *cid = @([cidStr integerValue]);
NSString *emoji = mc.emoji ? mc.emoji : @"";
[self.homeVM addUserCharacterWithId:cid emoji : emoji
completion:^(BOOL success, NSError * _Nullable error) {
if (!success) {
NSString *msg = error.localizedDescription ?: KBLocalized(@"Network error");
[KBHUD showInfo:msg];
return;
}
// 添加成功:更新模型状态并刷新当前行(按钮变为已添加且不可再点)
mc.added = YES;
NSMutableArray *m = [self.listCharacters mutableCopy];
[m replaceObjectAtIndex:current.row withObject:mc];
self.listCharacters = [m copy];
[self.tableView reloadRowsAtIndexPaths:@[current] withRowAnimation:UITableViewRowAnimationNone];
// 同步更新顶部前三名的展示状态
[self kb_refreshTopThreeView];
}];
};
return cell;
}
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 84.0;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// KBSearchVC *vc = [[KBSearchVC alloc] init];
// [self.navigationController pushViewController:vc animated:true];
// UINavigationController *nav = KB_CURRENT_NAV;
// [nav pushViewController:vc animated:true];
NSLog(@"===");
// 点击卡片 -> 展示弹窗
KBCharacter *c = self.listCharacters[indexPath.row];
// 自定义内容视图(尺寸可按需调节)
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.character = c;
// 创建并弹出
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 - Lazy
- (BaseTableView *)tableView {
if (!_tableView) {
// 使用 BaseTableView统一默认配置
_tableView = [[BaseTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // 设计为卡片式,去掉系统分割线
_tableView.showsVerticalScrollIndicator = NO;
_tableView.contentInset = UIEdgeInsetsMake(8, 0, KB_SafeAreaBottom(), 0);
[_tableView registerClass:HomeHotCell.class forCellReuseIdentifier:HomeHotCell.reuseId];
}
return _tableView;
}
@end