重构 Mine 模块为个人主页模式

 完成功能:
1. EPMineViewController 重构
   - 从菜单列表模式改为个人主页模式
   - 渐变背景(深紫到蓝)
   - 顶部个人信息卡片 + 底部用户动态列表
   - 复用 EPMomentCell 显示动态

2. EPMineHeaderView 新建
   - 大圆形头像(120x120,白色边框)
   - 昵称 + ID 显示
   - 关注/粉丝按钮
   - 右上角设置按钮
   - 渐变背景适配

3. 数据加载优化
   - 用户信息加载(真实 API)
   - 用户动态列表(分页加载)
   - 下拉刷新功能
   - 自动加载更多

4. 文件重命名
   - EPMomentCell(原 NewMomentCell)
   - EPMineHeaderView(新建)
   - 更新 Bridging Header

技术亮点:
- 个人主页模式完全不同于原版菜单模式
- 渐变背景 + 毛玻璃效果
- 复用 EPMomentCell 减少开发量
- 真实 API 集成

下一步:
- 修复编译错误(文件未添加到 Xcode 项目)
- 继续 v0.2 版本准备
This commit is contained in:
edwinQQQ
2025-10-10 15:05:07 +08:00
parent 099b27ed15
commit 12a8ef9a62
4 changed files with 236 additions and 385 deletions

View File

@@ -1,5 +1,5 @@
//
// NewMineHeaderView.h
// EPMineHeaderView.h
// YuMi
//
// Created by AI on 2025-10-09.
@@ -10,14 +10,14 @@
NS_ASSUME_NONNULL_BEGIN
/// 新的个人中心头部视图
/// 纵向卡片式设计 + 渐变背景
/// EP 系列个人主页头部视图
/// 大圆形头像 + 渐变背景 + 用户信息展示
@interface EPMineHeaderView : UIView
/// 配置用户信息
/// @param userInfo 用户信息字典
- (void)configureWithUserInfo:(NSDictionary *)userInfo;
/// 更新用户信息
/// @param userInfoDict 用户信息字典
- (void)updateWithUserInfo:(NSDictionary *)userInfoDict;
@end
NS_ASSUME_NONNULL_END
NS_ASSUME_NONNULL_END

View File

@@ -1,5 +1,5 @@
//
// NewMineHeaderView.m
// EPMineHeaderView.m
// YuMi
//
// Created by AI on 2025-10-09.
@@ -8,47 +8,32 @@
#import "EPMineHeaderView.h"
#import <Masonry/Masonry.h>
#import <SDWebImage/SDWebImage.h>
@interface EPMineHeaderView ()
// MARK: - UI Components
///
@property (nonatomic, strong) CAGradientLayer *gradientLayer;
///
///
@property (nonatomic, strong) UIImageView *avatarImageView;
///
///
@property (nonatomic, strong) UILabel *nicknameLabel;
///
@property (nonatomic, strong) UILabel *levelLabel;
/// ID
@property (nonatomic, strong) UILabel *idLabel;
///
@property (nonatomic, strong) UIView *progressContainer;
///
@property (nonatomic, strong) UIButton *settingsButton;
///
@property (nonatomic, strong) UIView *progressBar;
///
@property (nonatomic, strong) UIButton *followButton;
///
@property (nonatomic, strong) UILabel *expLabel;
///
@property (nonatomic, strong) UIView *statsContainer;
///
@property (nonatomic, strong) UILabel *followingLabel;
///
@property (nonatomic, strong) UILabel *followersLabel;
///
@property (nonatomic, strong) UIButton *fansButton;
@end
@implementation EPMineHeaderView
// MARK: - Lifecycle
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupUI];
@@ -56,223 +41,125 @@
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
//
self.gradientLayer.frame = self.bounds;
}
// MARK: - Setup UI
- (void)setupUI {
//
self.gradientLayer = [CAGradientLayer layer];
self.gradientLayer.colors = @[
(id)[UIColor colorWithRed:0.2 green:0.6 blue:0.86 alpha:1.0].CGColor, //
(id)[UIColor colorWithRed:0.3 green:0.5 blue:0.9 alpha:1.0].CGColor, //
];
self.gradientLayer.startPoint = CGPointMake(0, 0);
self.gradientLayer.endPoint = CGPointMake(1, 1);
[self.layer insertSublayer:self.gradientLayer atIndex:0];
//
//
self.avatarImageView = [[UIImageView alloc] init];
self.avatarImageView.layer.cornerRadius = 60;
self.avatarImageView.layer.masksToBounds = YES;
self.avatarImageView.layer.borderWidth = 3;
self.avatarImageView.layer.borderColor = [UIColor whiteColor].CGColor;
self.avatarImageView.backgroundColor = [UIColor whiteColor];
self.avatarImageView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:self.avatarImageView];
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self);
make.top.equalTo(self).offset(40);
make.size.mas_equalTo(CGSizeMake(80, 80));
make.top.equalTo(self).offset(60);
make.size.mas_equalTo(CGSizeMake(120, 120));
}];
//
self.nicknameLabel = [[UILabel alloc] init];
self.nicknameLabel.font = [UIFont boldSystemFontOfSize:24];
self.nicknameLabel.textColor = [UIColor whiteColor];
self.nicknameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:self.nicknameLabel];
[self.nicknameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self);
make.top.equalTo(self.avatarImageView.mas_bottom).offset(15);
make.top.equalTo(self.avatarImageView.mas_bottom).offset(16);
}];
//
[self addSubview:self.levelLabel];
[self.levelLabel mas_makeConstraints:^(MASConstraintMaker *make) {
// ID
self.idLabel = [[UILabel alloc] init];
self.idLabel.font = [UIFont systemFontOfSize:14];
self.idLabel.textColor = [UIColor whiteColor];
self.idLabel.alpha = 0.8;
self.idLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview:self.idLabel];
[self.idLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self);
make.top.equalTo(self.nicknameLabel.mas_bottom).offset(8);
}];
//
[self addSubview:self.progressContainer];
[self.progressContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self).offset(40);
make.right.equalTo(self).offset(-40);
make.top.equalTo(self.levelLabel.mas_bottom).offset(15);
make.height.mas_equalTo(8);
//
self.settingsButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.settingsButton setImage:[UIImage systemImageNamed:@"gearshape"] forState:UIControlStateNormal];
self.settingsButton.tintColor = [UIColor whiteColor];
self.settingsButton.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.2];
self.settingsButton.layer.cornerRadius = 20;
[self.settingsButton addTarget:self action:@selector(settingsButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:self.settingsButton];
[self.settingsButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self).offset(50);
make.right.equalTo(self).offset(-20);
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
//
[self.progressContainer addSubview:self.progressBar];
[self.progressBar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(self.progressContainer);
make.width.equalTo(self.progressContainer).multipliedBy(0.7); // 70%
//
self.followButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.followButton setTitle:@"关注" forState:UIControlStateNormal];
[self.followButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
self.followButton.titleLabel.font = [UIFont systemFontOfSize:16];
self.followButton.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.2];
self.followButton.layer.cornerRadius = 20;
[self addSubview:self.followButton];
[self.followButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.idLabel.mas_bottom).offset(20);
make.centerX.equalTo(self).offset(-50);
make.size.mas_equalTo(CGSizeMake(80, 40));
}];
//
[self addSubview:self.expLabel];
[self.expLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self);
make.top.equalTo(self.progressContainer.mas_bottom).offset(6);
}];
//
self.fansButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.fansButton setTitle:@"粉丝" forState:UIControlStateNormal];
[self.fansButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
self.fansButton.titleLabel.font = [UIFont systemFontOfSize:16];
self.fansButton.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.2];
self.fansButton.layer.cornerRadius = 20;
[self addSubview:self.fansButton];
//
[self addSubview:self.statsContainer];
[self.statsContainer mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self);
make.top.equalTo(self.expLabel.mas_bottom).offset(20);
make.height.mas_equalTo(60);
make.bottom.equalTo(self).offset(-15);
}];
//
[self.statsContainer addSubview:self.followingLabel];
[self.followingLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.statsContainer.mas_centerX).offset(-20);
make.centerY.equalTo(self.statsContainer);
}];
//
[self.statsContainer addSubview:self.followersLabel];
[self.followersLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.statsContainer.mas_centerX).offset(20);
make.centerY.equalTo(self.statsContainer);
[self.fansButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.idLabel.mas_bottom).offset(20);
make.centerX.equalTo(self).offset(50);
make.size.mas_equalTo(CGSizeMake(80, 40));
}];
}
// MARK: - Public Methods
- (void)configureWithUserInfo:(NSDictionary *)userInfo {
//
self.nicknameLabel.text = userInfo[@"nickname"] ?: @"未设置昵称";
- (void)updateWithUserInfo:(NSDictionary *)userInfoDict {
//
NSString *nickname = userInfoDict[@"nickname"] ?: @"未设置昵称";
self.nicknameLabel.text = nickname;
//
NSNumber *level = userInfo[@"level"];
self.levelLabel.text = [NSString stringWithFormat:@"Lv.%@", level ?: @"0"];
// ID
NSString *uid = userInfoDict[@"uid"] ?: @"";
self.idLabel.text = [NSString stringWithFormat:@"ID:%@", uid];
//
NSNumber *exp = userInfo[@"exp"];
NSNumber *nextLevelExp = userInfo[@"nextLevelExp"];
CGFloat progress = [exp floatValue] / [nextLevelExp floatValue];
[self.progressBar mas_remakeConstraints:^(MASConstraintMaker *make) {
make.left.top.bottom.equalTo(self.progressContainer);
make.width.equalTo(self.progressContainer).multipliedBy(MAX(0.1, MIN(1.0, progress)));
}];
self.expLabel.text = [NSString stringWithFormat:@"%@ / %@", exp, nextLevelExp];
//
NSNumber *following = userInfoDict[@"following"] ?: @0;
[self.followButton setTitle:[NSString stringWithFormat:@"关注 %@", following] forState:UIControlStateNormal];
//
NSNumber *followers = userInfo[@"followers"];
NSNumber *following = userInfo[@"following"];
self.followingLabel.text = [NSString stringWithFormat:@"关注\n%@", following ?: @"0"];
self.followersLabel.text = [NSString stringWithFormat:@"粉丝\n%@", followers ?: @"0"];
//
NSNumber *followers = userInfoDict[@"followers"] ?: @0;
[self.fansButton setTitle:[NSString stringWithFormat:@"粉丝 %@", followers] forState:UIControlStateNormal];
NSLog(@"[NewMineHeaderView] 用户信息已配置: %@", userInfo[@"nickname"]);
}
// MARK: - Lazy Loading
- (UIImageView *)avatarImageView {
if (!_avatarImageView) {
_avatarImageView = [[UIImageView alloc] init];
_avatarImageView.backgroundColor = [UIColor whiteColor];
_avatarImageView.layer.cornerRadius = 16; //
_avatarImageView.layer.masksToBounds = YES;
_avatarImageView.layer.borderWidth = 3;
_avatarImageView.layer.borderColor = [UIColor whiteColor].CGColor;
_avatarImageView.contentMode = UIViewContentModeScaleAspectFill;
//
NSString *avatarURL = userInfoDict[@"avatar"];
if (avatarURL && avatarURL.length > 0) {
[self.avatarImageView sd_setImageWithURL:[NSURL URLWithString:avatarURL]
placeholderImage:[UIImage imageNamed:@"default_avatar"]];
} else {
// 使
self.avatarImageView.image = [UIImage imageNamed:@"default_avatar"];
}
return _avatarImageView;
}
- (UILabel *)nicknameLabel {
if (!_nicknameLabel) {
_nicknameLabel = [[UILabel alloc] init];
_nicknameLabel.font = [UIFont systemFontOfSize:20 weight:UIFontWeightBold];
_nicknameLabel.textColor = [UIColor whiteColor];
_nicknameLabel.textAlignment = NSTextAlignmentCenter;
}
return _nicknameLabel;
- (void)settingsButtonTapped {
NSLog(@"[EPMineHeaderView] 设置按钮点击");
// TODO:
}
- (UILabel *)levelLabel {
if (!_levelLabel) {
_levelLabel = [[UILabel alloc] init];
_levelLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
_levelLabel.textColor = [UIColor colorWithWhite:1.0 alpha:0.9];
_levelLabel.textAlignment = NSTextAlignmentCenter;
_levelLabel.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.2];
_levelLabel.layer.cornerRadius = 12;
_levelLabel.layer.masksToBounds = YES;
//
_levelLabel.text = @" Lv.0 ";
}
return _levelLabel;
}
- (UIView *)progressContainer {
if (!_progressContainer) {
_progressContainer = [[UIView alloc] init];
_progressContainer.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.3];
_progressContainer.layer.cornerRadius = 4;
_progressContainer.layer.masksToBounds = YES;
}
return _progressContainer;
}
- (UIView *)progressBar {
if (!_progressBar) {
_progressBar = [[UIView alloc] init];
_progressBar.backgroundColor = [UIColor whiteColor];
_progressBar.layer.cornerRadius = 4;
_progressBar.layer.masksToBounds = YES;
}
return _progressBar;
}
- (UILabel *)expLabel {
if (!_expLabel) {
_expLabel = [[UILabel alloc] init];
_expLabel.font = [UIFont systemFontOfSize:12];
_expLabel.textColor = [UIColor colorWithWhite:1.0 alpha:0.8];
_expLabel.textAlignment = NSTextAlignmentCenter;
}
return _expLabel;
}
- (UIView *)statsContainer {
if (!_statsContainer) {
_statsContainer = [[UIView alloc] init];
_statsContainer.backgroundColor = [UIColor clearColor];
}
return _statsContainer;
}
- (UILabel *)followingLabel {
if (!_followingLabel) {
_followingLabel = [[UILabel alloc] init];
_followingLabel.font = [UIFont systemFontOfSize:14];
_followingLabel.textColor = [UIColor whiteColor];
_followingLabel.textAlignment = NSTextAlignmentCenter;
_followingLabel.numberOfLines = 2;
}
return _followingLabel;
}
- (UILabel *)followersLabel {
if (!_followersLabel) {
_followersLabel = [[UILabel alloc] init];
_followersLabel.font = [UIFont systemFontOfSize:14];
_followersLabel.textColor = [UIColor whiteColor];
_followersLabel.textAlignment = NSTextAlignmentCenter;
_followersLabel.numberOfLines = 2;
}
return _followersLabel;
}
@end
@end