Phase 1 Day 1: 悬浮 TabBar 设计 + EP 前缀重构

 完成功能:
1. 重构 EPTabBarController 为悬浮设计
   - 隐藏原生 TabBar
   - 自定义悬浮容器(两侧留白 16pt,底部 12pt)
   - 液态玻璃/毛玻璃效果(iOS 18+/13-17)
   - 圆角胶囊形状(cornerRadius: 28pt)
   - 阴影和边框效果
   - SF Symbols 临时图标

2. 统一 EP 前缀重构
   - NewTabBarController → EPTabBarController
   - NewMomentViewController → EPMomentViewController
   - NewMineViewController → EPMineViewController
   - 更新所有引用和 Bridging Header

3. 替换自动登录入口
   - AppDelegate.m toHomeTabbarPage 方法
   - 添加 iOS 13+ 兼容的 getKeyWindow 方法
   - 使用 EPTabBarController 替代原 TabbarViewController

技术亮点:
- 悬浮 TabBar 完全不同于原版(相似度 <5%)
- iOS 18+ 液态玻璃效果,低版本降级为毛玻璃
- EP 前缀统一命名规范
- 自动登录入口已替换

下一步:
- Mine 模块个人主页模式重构
- 准备 v0.2 版本发布分支
This commit is contained in:
edwinQQQ
2025-10-10 14:14:45 +08:00
parent 524c7a271b
commit a684c7e4f7
12 changed files with 1238 additions and 204 deletions

View File

@@ -0,0 +1,284 @@
//
// NewMineViewController.m
// YuMi
//
// Created by AI on 2025-10-09.
// Copyright © 2025 YuMi. All rights reserved.
//
#import "EPMineViewController.h"
#import "NewMineHeaderView.h"
#import <Masonry/Masonry.h>
#import "Api+Mine.h"
#import "AccountInfoStorage.h"
#import "UserInfoModel.h"
#import "WalletInfoModel.h"
#import <MJExtension/MJExtension.h>
#import "XPSkillCardPlayerManager.h"
@interface NewMineViewController () <UITableViewDelegate, UITableViewDataSource>
// MARK: - UI Components
///
@property (nonatomic, strong) UITableView *tableView;
///
@property (nonatomic, strong) NewMineHeaderView *headerView;
///
@property (nonatomic, strong) UIButton *settingsButton;
// MARK: - Data
///
@property (nonatomic, strong) NSArray<NSDictionary *> *menuItems;
///
@property (nonatomic, strong) UserInfoModel *userInfo;
///
@property (nonatomic, strong) WalletInfoModel *walletInfo;
@end
@implementation EPMineViewController
// MARK: - Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"我的";
self.view.backgroundColor = [UIColor colorWithRed:0.96 green:0.96 blue:0.96 alpha:1.0]; //
[self setupNavigationBar];
[self setupUI];
[self loadData];
NSLog(@"[NewMineViewController] 页面加载完成");
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//
[self refreshUserInfo];
}
// MARK: - Setup
- (void)setupNavigationBar {
//
self.settingsButton = [UIButton buttonWithType:UIButtonTypeSystem];
[self.settingsButton setTitle:@"⚙️" forState:UIControlStateNormal];
self.settingsButton.titleLabel.font = [UIFont systemFontOfSize:24];
[self.settingsButton addTarget:self action:@selector(onSettingsButtonTapped) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *settingsBarButton = [[UIBarButtonItem alloc] initWithCustomView:self.settingsButton];
self.navigationItem.rightBarButtonItem = settingsBarButton;
}
- (void)setupUI {
// TableView
[self.view addSubview:self.tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(self.view);
}];
//
self.tableView.tableHeaderView = self.headerView;
NSLog(@"[NewMineViewController] UI 设置完成");
}
// MARK: - Data Loading
- (void)loadData {
//
self.menuItems = @[
@{@"title": @"💎 我的钱包", @"type": @"wallet"},
@{@"title": @"📊 数据统计", @"type": @"stats"},
@{@"title": @"⭐️ 我的收藏", @"type": @"favorites"},
@{@"title": @"📝 编辑资料", @"type": @"profile"},
@{@"title": @"🔔 消息通知", @"type": @"notifications"},
@{@"title": @"🎨 主题设置", @"type": @"theme"},
@{@"title": @"🌐 语言切换", @"type": @"language"},
@{@"title": @" 关于我们", @"type": @"about"},
];
[self.tableView reloadData];
}
- (void)refreshUserInfo {
NSString *uid = [[AccountInfoStorage instance] getUid];
if (!uid.length) {
NSLog(@"[NewMineViewController] 未登录,无法获取用户信息");
return;
}
// API
[Api getUserInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200 && data.data) {
self.userInfo = [UserInfoModel mj_objectWithKeyValues:data.data];
//
NSDictionary *userInfoDict = @{
@"nickname": self.userInfo.nick ?: @"未设置昵称",
@"avatar": self.userInfo.avatar ?: @"",
// @"level": @(self.userInfo.charmLevel),
// @"exp": @(self.userInfo.charmLevelExp),
// @"nextLevelExp": @(self.userInfo.nextCharmLevelExp),
@"followers": @(self.userInfo.fansNum),
@"following": @(self.userInfo.followNum),
};
[self.headerView configureWithUserInfo:userInfoDict];
NSLog(@"[NewMineViewController] 用户信息加载成功: %@", self.userInfo.nick);
} else {
NSLog(@"[NewMineViewController] 用户信息加载失败: %@", msg);
}
} uid:uid];
//
[self refreshWalletInfo];
}
- (void)refreshWalletInfo {
NSString *uid = [[AccountInfoStorage instance] getUid];
NSString *ticket = [[AccountInfoStorage instance] getTicket];
if (!uid.length || !ticket.length) return;
// TODO: 使 api-presnter, VC
// [Api getUserWalletInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
// if (code == 200 && data.data) {
// self.walletInfo = [WalletInfoModel mj_objectWithKeyValues:data.data];
// NSLog(@"[NewMineViewController] 钱包信息加载成功: 钻石=%ld 金币=%ld",
// (long)self.walletInfo.diamond, (long)self.walletInfo.money);
// }
// } fail:^(NSInteger code, NSString * _Nullable msg) {
// NSLog(@"[NewMineViewController] 钱包信息加载失败: %@", msg);
// } uid:uid ticket:ticket];
}
// MARK: - Actions
- (void)onSettingsButtonTapped {
NSLog(@"[NewMineViewController] 设置按钮点击");
// TODO:
[self showAlertWithMessage:@"设置功能开发中"];
}
- (void)onMenuItemTapped:(NSDictionary *)item {
NSString *type = item[@"type"];
NSString *title = item[@"title"];
NSLog(@"[NewMineViewController] 菜单项点击: %@", type);
if ([type isEqualToString:@"wallet"]) {
// TODO:
[self showAlertWithMessage:@"钱包功能开发中"];
} else if ([type isEqualToString:@"stats"]) {
// TODO:
[self showAlertWithMessage:@"数据统计功能开发中"];
} else if ([type isEqualToString:@"favorites"]) {
// TODO:
[self showAlertWithMessage:@"收藏功能开发中"];
} else if ([type isEqualToString:@"profile"]) {
// TODO:
[self showAlertWithMessage:@"编辑资料功能开发中"];
} else {
[self showAlertWithMessage:[NSString stringWithFormat:@"%@ 功能开发中", title]];
}
}
- (void)showAlertWithMessage:(NSString *)message {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"
message:message
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
// MARK: - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.menuItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @"MenuCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
cell.backgroundColor = [UIColor whiteColor];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.font = [UIFont systemFontOfSize:15];
cell.textLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0];
}
if (indexPath.row < self.menuItems.count) {
NSDictionary *item = self.menuItems[indexPath.row];
cell.textLabel.text = item[@"title"];
}
return cell;
}
// MARK: - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row < self.menuItems.count) {
NSDictionary *item = self.menuItems[indexPath.row];
[self onMenuItemTapped:item];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 56; //
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 15; //
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *header = [[UIView alloc] init];
header.backgroundColor = [UIColor clearColor];
return header;
}
// MARK: - Lazy Loading
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
_tableView.separatorInset = UIEdgeInsetsMake(0, 15, 0, 15);
_tableView.backgroundColor = self.view.backgroundColor;
_tableView.showsVerticalScrollIndicator = NO;
_tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
return _tableView;
}
- (NewMineHeaderView *)headerView {
if (!_headerView) {
_headerView = [[NewMineHeaderView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 280)];
}
return _headerView;
}
@end