// // EPMineHeaderView.m // YuMi // // Created by AI on 2025-10-09. // Copyright © 2025 YuMi. All rights reserved. // #import "EPMineHeaderView.h" #import #import #import "EPEmotionColorStorage.h" @interface EPMineHeaderView () /// 头像视图 @property (nonatomic, strong) UIImageView *avatarImageView; /// 呼吸光晕层 @property (nonatomic, strong) CALayer *glowLayer; /// 昵称标签 @property (nonatomic, strong) UILabel *nicknameLabel; /// ID 标签 @property (nonatomic, strong) UILabel *idLabel; /// 设置按钮 @property (nonatomic, strong) UIButton *settingsButton; @end @implementation EPMineHeaderView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self setupUI]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; // 更新光晕层 frame(跟随头像位置) if (self.glowLayer) { self.glowLayer.frame = CGRectInset(self.avatarImageView.frame, -8, -8); } } - (void)setupUI { // 大圆形头像 self.avatarImageView = [[UIImageView alloc] init]; self.avatarImageView.layer.cornerRadius = 60; self.avatarImageView.layer.masksToBounds = NO; // 改为 NO 以显示阴影 self.avatarImageView.layer.borderWidth = 0; // 移除边框 self.avatarImageView.backgroundColor = [UIColor whiteColor]; self.avatarImageView.contentMode = UIViewContentModeScaleAspectFill; // 为了同时显示圆角和阴影,需要设置 clipsToBounds self.avatarImageView.clipsToBounds = YES; [self addSubview:self.avatarImageView]; [self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) { make.centerX.equalTo(self); 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(16); }]; // 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.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.trailing.equalTo(self).offset(-20); make.size.mas_equalTo(CGSizeMake(40, 40)); }]; } - (void)updateWithUserInfo:(NSDictionary *)userInfoDict { // 更新昵称 NSString *nickname = userInfoDict[@"nickname"] ?: YMLocalizedString(@"user.nickname_not_set"); self.nicknameLabel.text = nickname; // 更新 ID NSString *uid = userInfoDict[@"uid"] ?: @""; self.idLabel.text = [NSString stringWithFormat:@"ID:%@", uid]; // 加载头像 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"]; } // 应用用户专属情绪颜色 [self applyUserSignatureColor]; } /// 应用用户专属情绪颜色到头像边框和阴影 - (void)applyUserSignatureColor { NSString *signatureColor = [EPEmotionColorStorage userSignatureColor]; if (signatureColor) { // 有专属颜色,使用该颜色 UIColor *color = [self colorFromHex:signatureColor]; // 取消边框 self.avatarImageView.layer.borderWidth = 0; // 设置阴影(使用情绪颜色) self.avatarImageView.layer.shadowColor = color.CGColor; self.avatarImageView.layer.shadowOffset = CGSizeMake(0, 4); self.avatarImageView.layer.shadowOpacity = 0.6; self.avatarImageView.layer.shadowRadius = 12; NSLog(@"[EPMineHeaderView] 应用专属颜色: %@", signatureColor); // 应用呼吸光晕动效 ⭐ [self applyBreathingGlow]; } else { // 没有专属颜色,保持无边框 self.avatarImageView.layer.borderWidth = 0; // 默认轻微阴影 self.avatarImageView.layer.shadowColor = [UIColor blackColor].CGColor; self.avatarImageView.layer.shadowOffset = CGSizeMake(0, 2); self.avatarImageView.layer.shadowOpacity = 0.2; self.avatarImageView.layer.shadowRadius = 8; // 移除光晕层 if (self.glowLayer) { [self.glowLayer removeFromSuperlayer]; self.glowLayer = nil; } } } /// 应用呼吸光晕动效 - (void)applyBreathingGlow { NSString *signatureColor = [EPEmotionColorStorage userSignatureColor]; if (!signatureColor) return; UIColor *color = [self colorFromHex:signatureColor]; // 创建光晕层(如果不存在) if (!self.glowLayer) { self.glowLayer = [CALayer layer]; self.glowLayer.frame = CGRectInset(self.avatarImageView.frame, -8, -8); // 比头像大 16pt self.glowLayer.cornerRadius = 68; // 头像 60 + 扩展 8 self.glowLayer.backgroundColor = [color colorWithAlphaComponent:0.75].CGColor; // 大幅加深 // 插入到头像 layer 下方 [self.layer insertSublayer:self.glowLayer below:self.avatarImageView.layer]; } else { // 更新颜色 self.glowLayer.backgroundColor = [color colorWithAlphaComponent:0.75].CGColor; // 大幅加深 } // 移除旧动画 [self.glowLayer removeAllAnimations]; // 创建呼吸动画组 CAAnimationGroup *breathingGroup = [CAAnimationGroup animation]; breathingGroup.duration = 1.8; // 加速 breathingGroup.repeatCount = HUGE_VALF; // 无限循环 breathingGroup.autoreverses = YES; breathingGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; // 动画 1:透明度变化(呼吸亮度) CABasicAnimation *opacityAnim = [CABasicAnimation animationWithKeyPath:@"opacity"]; opacityAnim.fromValue = @(0.65); opacityAnim.toValue = @(1.0); // 接近完全不透明,颜色饱和 // 动画 2:缩放变化(呼吸扩散) CABasicAnimation *scaleAnim = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; scaleAnim.fromValue = @(1.0); scaleAnim.toValue = @(1.1); breathingGroup.animations = @[opacityAnim, scaleAnim]; [self.glowLayer addAnimation:breathingGroup forKey:@"breathing"]; NSLog(@"[EPMineHeaderView] 启动呼吸光晕动效"); } /// Hex 转 UIColor - (UIColor *)colorFromHex:(NSString *)hexString { unsigned rgbValue = 0; NSScanner *scanner = [NSScanner scannerWithString:hexString]; [scanner setScanLocation:1]; // 跳过 # [scanner scanHexInt:&rgbValue]; return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0]; } - (void)settingsButtonTapped { NSLog(@"[EPMineHeaderView] 设置按钮点击"); // 使用 block 回调 if (self.onSettingsButtonTapped) { self.onSettingsButtonTapped(); } } @end