diff --git a/keyBoard.xcodeproj/project.pbxproj b/keyBoard.xcodeproj/project.pbxproj index cbbd385..7a38435 100644 --- a/keyBoard.xcodeproj/project.pbxproj +++ b/keyBoard.xcodeproj/project.pbxproj @@ -82,6 +82,8 @@ 049FB2172EC20A6600FAB05D /* BMLongPressDragCellCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2132EC20A6600FAB05D /* BMLongPressDragCellCollectionView.m */; }; 049FB21A2EC20A9E00FAB05D /* KBMyKeyBoardVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2192EC20A9E00FAB05D /* KBMyKeyBoardVC.m */; }; 049FB2202EC30D2700FAB05D /* HomeRankDetailPopView.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB21F2EC30D2700FAB05D /* HomeRankDetailPopView.m */; }; + 049FB2232EC311F900FAB05D /* KBPersonInfoVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2222EC311F900FAB05D /* KBPersonInfoVC.m */; }; + 049FB2262EC3136D00FAB05D /* KBPersonInfoItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB2252EC3136D00FAB05D /* KBPersonInfoItemCell.m */; }; 049FB31D2EC21BCD00FAB05D /* KBMyKeyboardCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 049FB31C2EC21BCD00FAB05D /* KBMyKeyboardCell.m */; }; 04A9FE0F2EB481100020DB6D /* KBHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 04FC97082EB31B14007BD342 /* KBHUD.m */; }; 04A9FE132EB4D0D20020DB6D /* KBFullAccessManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 04A9FE112EB4D0D20020DB6D /* KBFullAccessManager.m */; }; @@ -287,6 +289,10 @@ 049FB2192EC20A9E00FAB05D /* KBMyKeyBoardVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyKeyBoardVC.m; sourceTree = ""; }; 049FB21E2EC30D2700FAB05D /* HomeRankDetailPopView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HomeRankDetailPopView.h; sourceTree = ""; }; 049FB21F2EC30D2700FAB05D /* HomeRankDetailPopView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HomeRankDetailPopView.m; sourceTree = ""; }; + 049FB2212EC311F900FAB05D /* KBPersonInfoVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPersonInfoVC.h; sourceTree = ""; }; + 049FB2222EC311F900FAB05D /* KBPersonInfoVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPersonInfoVC.m; sourceTree = ""; }; + 049FB2242EC3136D00FAB05D /* KBPersonInfoItemCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBPersonInfoItemCell.h; sourceTree = ""; }; + 049FB2252EC3136D00FAB05D /* KBPersonInfoItemCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBPersonInfoItemCell.m; sourceTree = ""; }; 049FB31B2EC21BCD00FAB05D /* KBMyKeyboardCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBMyKeyboardCell.h; sourceTree = ""; }; 049FB31C2EC21BCD00FAB05D /* KBMyKeyboardCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KBMyKeyboardCell.m; sourceTree = ""; }; 04A9A67D2EB9E1690023B8F4 /* KBResponderUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KBResponderUtils.h; sourceTree = ""; }; @@ -877,6 +883,8 @@ 04890B112EC2F00000FABA60 /* KBMyHeaderView.m */, 049FB20F2EC1F72F00FAB05D /* KBMyListCell.h */, 049FB2102EC1F72F00FAB05D /* KBMyListCell.m */, + 049FB2242EC3136D00FAB05D /* KBPersonInfoItemCell.h */, + 049FB2252EC3136D00FAB05D /* KBPersonInfoItemCell.m */, ); path = V; sourceTree = ""; @@ -892,6 +900,8 @@ 048908DF2EBF73DC00FABA60 /* MySkinVC.m */, 048908E12EBF821700FABA60 /* KBSkinDetailVC.h */, 048908E22EBF821700FABA60 /* KBSkinDetailVC.m */, + 049FB2212EC311F900FAB05D /* KBPersonInfoVC.h */, + 049FB2222EC311F900FAB05D /* KBPersonInfoVC.m */, ); path = VC; sourceTree = ""; @@ -1418,6 +1428,7 @@ 048908DD2EBF67EB00FABA60 /* KBSearchResultVC.m in Sources */, 047C65102EBCA8DD0035E841 /* HomeRankContentVC.m in Sources */, 047C655C2EBCD0F80035E841 /* UIView+KBShadow.m in Sources */, + 049FB2262EC3136D00FAB05D /* KBPersonInfoItemCell.m in Sources */, 048908C32EBE32B800FABA60 /* KBSearchVC.m in Sources */, 049FB20B2EC1C13800FAB05D /* KBSkinBottomActionView.m in Sources */, 047C655E2EBCD5B20035E841 /* UIImage+KBColor.m in Sources */, @@ -1435,6 +1446,7 @@ 04FC97062EB30A00007BD342 /* KBGuideUserCell.m in Sources */, 04FC97092EB31B14007BD342 /* KBHUD.m in Sources */, 04FC970E2EB334F8007BD342 /* UIImageView+KBWebImage.m in Sources */, + 049FB2232EC311F900FAB05D /* KBPersonInfoVC.m in Sources */, 048908FE2EC0CC2400FABA60 /* UIScrollView+KBEmptyView.m in Sources */, 04FC970F2EB334F8007BD342 /* KBWebImageManager.m in Sources */, 04FC95CF2EB1E7A1007BD342 /* HomeVC.m in Sources */, diff --git a/keyBoard/Class/Me/V/KBMyHeaderView.m b/keyBoard/Class/Me/V/KBMyHeaderView.m index 29f55bc..f92d15a 100644 --- a/keyBoard/Class/Me/V/KBMyHeaderView.m +++ b/keyBoard/Class/Me/V/KBMyHeaderView.m @@ -6,6 +6,7 @@ #import "KBMyHeaderView.h" #import #import "UIColor+Extension.h" +#import "KBPersonInfoVC.h" @interface KBMyHeaderView () @property (nonatomic, strong) UILabel *titleLabel; @@ -193,7 +194,10 @@ #pragma mark - Actions - (void)onKeyboardTap { if (self.onKeyboardTapped) { self.onKeyboardTapped(); } } -- (void)onAvatarTap { if (self.onAvatarTapped) { self.onAvatarTapped(); } } +- (void)onAvatarTap { + KBPersonInfoVC *vc = [[KBPersonInfoVC alloc] init]; + [KB_CURRENT_NAV pushViewController:vc animated:true]; +} - (void)onLeftCardTap { if (self.onLeftCardTapped) { self.onLeftCardTapped(); } } - (void)onRightCardTap { if (self.onRightCardTapped) { self.onRightCardTapped(); } } diff --git a/keyBoard/Class/Me/V/KBPersonInfoItemCell.h b/keyBoard/Class/Me/V/KBPersonInfoItemCell.h new file mode 100644 index 0000000..2fc0891 --- /dev/null +++ b/keyBoard/Class/Me/V/KBPersonInfoItemCell.h @@ -0,0 +1,26 @@ +// +// KBPersonInfoItemCell.h +// keyBoard +// +// Created by Codex on 2025/11/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// 个人资料页面的条目 Cell(左标题,右文案/箭头/复制按钮) +@interface KBPersonInfoItemCell : UITableViewCell + +/// 配置 +- (void)configWithTitle:(NSString *)title + value:(NSString *)value + showArrow:(BOOL)showArrow + showCopy:(BOOL)showCopy + isTop:(BOOL)isTop + isBottom:(BOOL)isBottom; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/keyBoard/Class/Me/V/KBPersonInfoItemCell.m b/keyBoard/Class/Me/V/KBPersonInfoItemCell.m new file mode 100644 index 0000000..d5feafa --- /dev/null +++ b/keyBoard/Class/Me/V/KBPersonInfoItemCell.m @@ -0,0 +1,250 @@ +// +// KBPersonInfoItemCell.m +// keyBoard +// +// Created by Codex on 2025/11/11. +// + +@import UIKit; +#import "KBPersonInfoItemCell.h" +#import + +@interface KBPersonInfoItemCell () +// 白色圆角容器(实现卡片效果) +@property (nonatomic, strong) UIView *cardView; +// 标题(左) +@property (nonatomic, strong) UILabel *titleLabel; +// 值(右) +@property (nonatomic, strong) UILabel *valueLabel; +// 箭头(>) +@property (nonatomic, strong) UIImageView *arrowView; +// 复制按钮 +@property (nonatomic, strong) UIButton *copyBtn; +// 分割线 +@property (nonatomic, strong) UIView *line; +// 记录圆角位置,layoutSubviews 时更新 mask +@property (nonatomic, assign) UIRectCorner cornerRecord; +@end + +@implementation KBPersonInfoItemCell + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { + if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { + self.backgroundColor = UIColor.clearColor; + self.selectionStyle = UITableViewCellSelectionStyleNone; + + [self.contentView addSubview:self.cardView]; + [self.cardView addSubview:self.titleLabel]; + [self.cardView addSubview:self.valueLabel]; + [self.cardView addSubview:self.arrowView]; + [self.cardView addSubview:self.copyBtn]; + [self.cardView addSubview:self.line]; + + [self.cardView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.contentView).offset(16); + make.right.equalTo(self.contentView).offset(-16); + make.top.equalTo(self.contentView); + make.bottom.equalTo(self.contentView); + }]; + + [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.cardView).offset(16); + make.centerY.equalTo(self.cardView); + }]; + + [self.arrowView mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.equalTo(self.cardView).offset(-16); + make.centerY.equalTo(self.cardView); + make.width.mas_equalTo(10); + make.height.mas_equalTo(16); + }]; + + [self.copyBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.cardView); + make.right.equalTo(self.cardView).offset(-16); + make.width.height.mas_equalTo(22); + }]; + + [self.valueLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.cardView); + make.right.equalTo(self.arrowView.mas_left).offset(-8); + }]; + + [self.line mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.cardView).offset(16); + make.right.equalTo(self.cardView).offset(-16); + make.bottom.equalTo(self.cardView); + make.height.mas_equalTo(0.5); + }]; + } + return self; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + // 卡片圆角半径保持一致 + self.cardView.layer.cornerRadius = 12.0; + // 根据记录的 corner 重新生成 mask,保证尺寸变化后仍正确 + if (self.cornerRecord != 0 && !CGRectIsEmpty(self.cardView.bounds)) { + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.cardView.bounds + byRoundingCorners:self.cornerRecord + cornerRadii:CGSizeMake(12, 12)]; + CAShapeLayer *mask = [CAShapeLayer layer]; + mask.frame = self.cardView.bounds; mask.path = path.CGPath; + self.cardView.layer.mask = mask; + } else { + self.cardView.layer.mask = nil; + } +} + +- (void)prepareForReuse { + [super prepareForReuse]; + self.arrowView.hidden = YES; self.copyBtn.hidden = YES; + self.line.hidden = NO; +} + +- (void)configWithTitle:(NSString *)title + value:(NSString *)value + showArrow:(BOOL)showArrow + showCopy:(BOOL)showCopy + isTop:(BOOL)isTop + isBottom:(BOOL)isBottom { + self.titleLabel.text = title ?: @""; + self.valueLabel.text = value ?: @""; + self.arrowView.hidden = !showArrow; + self.copyBtn.hidden = !showCopy; + self.valueLabel.textColor = showArrow ? [UIColor blackColor] : [UIColor colorWithWhite:0.2 alpha:1.0]; + + // 当显示复制按钮时,值需要靠左到复制按钮左侧 + UIView *rightAnchor = showCopy ? self.copyBtn : self.arrowView; + [self.valueLabel mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerY.equalTo(self.cardView); + make.right.equalTo(rightAnchor.mas_left).offset(-8); + }]; + + // 顶部/底部圆角控制 + 分割线 + UIRectCorner corners = 0; + if (isTop && isBottom) { + corners = UIRectCornerAllCorners; + self.line.hidden = YES; + } else if (isTop) { + corners = UIRectCornerTopLeft | UIRectCornerTopRight; + self.line.hidden = NO; + } else if (isBottom) { + corners = UIRectCornerBottomLeft | UIRectCornerBottomRight; + self.line.hidden = YES; // 底部不需要分割线 + } else { + corners = 0; self.line.hidden = NO; + } + + // 使用遮罩实现指定圆角 + // 记录并等待 layoutSubviews 里按实际尺寸设置 mask + self.cornerRecord = corners; + [self setNeedsLayout]; +} + +#pragma mark - Lazy UI + +- (UIView *)cardView { + if (!_cardView) { + _cardView = [UIView new]; + _cardView.backgroundColor = UIColor.whiteColor; + _cardView.layer.cornerRadius = 12.0; + _cardView.layer.masksToBounds = YES; // 配合圆角 + } + return _cardView; +} + +- (UILabel *)titleLabel { + if (!_titleLabel) { + _titleLabel = [UILabel new]; + _titleLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1.0]; + _titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightRegular]; + } + return _titleLabel; +} + +- (UILabel *)valueLabel { + if (!_valueLabel) { + _valueLabel = [UILabel new]; + _valueLabel.textColor = [UIColor blackColor]; + _valueLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; + _valueLabel.textAlignment = NSTextAlignmentRight; + [_valueLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + } + return _valueLabel; +} + +- (UIImageView *)arrowView { + if (!_arrowView) { + _arrowView = [[UIImageView alloc] init]; + _arrowView.contentMode = UIViewContentModeScaleAspectFit; + UIImage *img = nil; + if (@available(iOS 13.0, *)) { + img = [UIImage systemImageNamed:@"chevron.right"]; + } + if (!img) { + // 简易绘制一个三角箭头作为兜底 + CGSize size = CGSizeMake(10, 16); + UIGraphicsBeginImageContextWithOptions(size, NO, 0); + UIBezierPath *p = [UIBezierPath bezierPath]; + [p moveToPoint:CGPointMake(2, 2)]; + [p addLineToPoint:CGPointMake(8, 8)]; + [p addLineToPoint:CGPointMake(2, 14)]; + [[UIColor colorWithWhite:0.7 alpha:1] setStroke]; + p.lineWidth = 2; [p stroke]; + img = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + } + _arrowView.image = img; + _arrowView.tintColor = [UIColor colorWithWhite:0.7 alpha:1]; + _arrowView.hidden = YES; + } + return _arrowView; +} + +- (UIButton *)copyBtn { + if (!_copyBtn) { + _copyBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + UIImage *img = nil; + if (@available(iOS 13.0, *)) { + img = [UIImage systemImageNamed:@"doc.on.doc"]; + } + if (!img) { + // 兜底绘制一个简单的 copy 图标 + CGSize sz = CGSizeMake(22, 22); + UIGraphicsBeginImageContextWithOptions(sz, NO, 0); + CGContextRef ctx = UIGraphicsGetCurrentContext(); + [[UIColor colorWithWhite:0.85 alpha:1] setStroke]; + CGContextSetLineWidth(ctx, 2); + CGContextStrokeRect(ctx, CGRectMake(6, 6, 12, 12)); + CGContextStrokeRect(ctx, CGRectMake(4, 4, 12, 12)); + img = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + } + [_copyBtn setImage:img forState:UIControlStateNormal]; + _copyBtn.tintColor = [UIColor colorWithWhite:0.6 alpha:1]; + _copyBtn.hidden = YES; + [_copyBtn addTarget:self action:@selector(onCopy) forControlEvents:UIControlEventTouchUpInside]; + } + return _copyBtn; +} + +- (UIView *)line { + if (!_line) { + _line = [UIView new]; + _line.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0]; + } + return _line; +} + +#pragma mark - Event + +- (void)onCopy { + // 简单示例:复制 valueLabel 文本 + NSString *txt = self.valueLabel.text ?: @""; + if (txt.length == 0) return; + UIPasteboard.generalPasteboard.string = txt; +} + +@end diff --git a/keyBoard/Class/Me/VC/KBPersonInfoVC.h b/keyBoard/Class/Me/VC/KBPersonInfoVC.h new file mode 100644 index 0000000..dcf3a5f --- /dev/null +++ b/keyBoard/Class/Me/VC/KBPersonInfoVC.h @@ -0,0 +1,16 @@ +// +// KBPersonInfoVC.h +// keyBoard +// +// Created by Mac on 2025/11/11. +// 个人资料 + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface KBPersonInfoVC : BaseViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/Me/VC/KBPersonInfoVC.m b/keyBoard/Class/Me/VC/KBPersonInfoVC.m new file mode 100644 index 0000000..a3e328c --- /dev/null +++ b/keyBoard/Class/Me/VC/KBPersonInfoVC.m @@ -0,0 +1,247 @@ +// +// KBPersonInfoVC.m +// keyBoard +// +// Created by Mac on 2025/11/11. +// + +// +// KBPersonInfoVC.m +// 个人资料 +// + +#import "KBPersonInfoVC.h" +#import +#import "KBPersonInfoItemCell.h" + +@interface KBPersonInfoVC () + +// 列表 +@property (nonatomic, strong) BaseTableView *tableView; // 懒加载 + +// 头像区(表头) +@property (nonatomic, strong) UIView *headerView; +@property (nonatomic, strong) UIImageView *avatarView; // 头像 +@property (nonatomic, strong) UIButton *editBadge; // 头像右下角的小铅笔 +@property (nonatomic, strong) UILabel *modifyLabel; // “Modify” 文案 + +// 底部退出(表尾) +@property (nonatomic, strong) UIView *footerView; +@property (nonatomic, strong) UIView *logoutBg; +@property (nonatomic, strong) UIButton *logoutBtn; + +// 数据 +@property (nonatomic, copy) NSArray *items; // {title,value,arrow,copy} + +@end + +@implementation KBPersonInfoVC + +- (void)viewDidLoad { + [super viewDidLoad]; + self.kb_titleLabel.text = @"Settings"; // 导航标题 + self.kb_navView.backgroundColor = [UIColor clearColor]; + self.view.backgroundColor = [UIColor colorWithHex:0xF8F8F8]; + + // 构造数据 + self.items = @[ + @{ @"title": @"Nickname", @"value": @"Nickname", @"arrow": @YES, @"copy": @NO }, + @{ @"title": @"Gender", @"value": @"Choose", @"arrow": @YES, @"copy": @NO }, + @{ @"title": @"User ID", @"value": @"8888888", @"arrow": @NO, @"copy": @YES }, + ]; + + [self.view addSubview:self.tableView]; + [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.bottom.equalTo(self.view); + make.top.equalTo(self.view).offset(KB_NAV_TOTAL_HEIGHT + 10); + }]; + + // 表头 & 表尾 + self.tableView.tableHeaderView = self.headerView; + self.tableView.tableFooterView = self.footerView; +} + +#pragma mark - UITableView + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.items.count; } + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { + return 56.0; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 12.0; } +- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { return [UIView new]; } +- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.01; } + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *cid = @"KBPersonInfoItemCell"; + KBPersonInfoItemCell *cell = [tableView dequeueReusableCellWithIdentifier:cid]; + if (!cell) { cell = [[KBPersonInfoItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cid]; } + NSDictionary *it = self.items[indexPath.row]; + BOOL isTop = (indexPath.row == 0); + BOOL isBottom = (indexPath.row == self.items.count - 1); + [cell configWithTitle:it[@"title"] + value:it[@"value"] + showArrow:[it[@"arrow"] boolValue] + showCopy:[it[@"copy"] boolValue] + isTop:isTop + isBottom:isBottom]; + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + // 示例:点击昵称/性别执行操作;用户 ID 行点击不处理(有复制按钮) + if (indexPath.row == 0) { + // TODO: 昵称编辑 + } else if (indexPath.row == 1) { + // TODO: 性别选择 + } +} + +#pragma mark - Actions + +- (void)onTapAvatarEdit { + // 示例:更换头像 +} + +- (void)onTapLogout { + // 示例:退出登录 +} + +#pragma mark - Lazy UI(懒加载) + +- (UITableView *)tableView { + if (!_tableView) { + // 使用 Plain,自行实现卡片留白与圆角,更贴近设计图 + _tableView = [[BaseTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; + _tableView.backgroundColor = UIColor.clearColor; + _tableView.showsVerticalScrollIndicator = NO; + _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // 自定义分割 + _tableView.dataSource = self; _tableView.delegate = self; + _tableView.contentInset = UIEdgeInsetsMake(8, 0, 16, 0); + } + return _tableView; +} + +- (UIView *)headerView { + if (!_headerView) { + CGFloat w = UIScreen.mainScreen.bounds.size.width; + UIView *hv = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 180)]; + hv.backgroundColor = UIColor.clearColor; + + [hv addSubview:self.avatarView]; + [hv addSubview:self.editBadge]; + [hv addSubview:self.modifyLabel]; + + [self.avatarView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.equalTo(hv); + make.top.equalTo(hv).offset(12); + make.width.height.mas_equalTo(96); + }]; + [self.editBadge mas_makeConstraints:^(MASConstraintMaker *make) { + make.width.height.mas_equalTo(24); + make.centerX.equalTo(self.avatarView.mas_right).offset(-8); + make.centerY.equalTo(self.avatarView.mas_bottom).offset(-8); + }]; + [self.modifyLabel mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.equalTo(self.avatarView.mas_bottom).offset(10); + make.centerX.equalTo(hv); + }]; + + _headerView = hv; + } + return _headerView; +} + +- (UIImageView *)avatarView { + if (!_avatarView) { + _avatarView = [[UIImageView alloc] init]; + _avatarView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; + _avatarView.layer.cornerRadius = 48; _avatarView.layer.masksToBounds = YES; + // 外白描边 + _avatarView.layer.borderWidth = 3.0; _avatarView.layer.borderColor = UIColor.whiteColor.CGColor; + // 占位图 + UIGraphicsBeginImageContextWithOptions(CGSizeMake(96, 96), NO, 0); + CGContextRef ctx = UIGraphicsGetCurrentContext(); + [[UIColor colorWithRed:0.86 green:0.95 blue:0.90 alpha:1] setFill]; + CGContextFillEllipseInRect(ctx, CGRectMake(0, 0, 96, 96)); + UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + _avatarView.image = img; + _avatarView.userInteractionEnabled = YES; + } + return _avatarView; +} + +- (UIButton *)editBadge { + if (!_editBadge) { + _editBadge = [UIButton buttonWithType:UIButtonTypeCustom]; + _editBadge.backgroundColor = [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0]; + _editBadge.layer.cornerRadius = 12; _editBadge.layer.masksToBounds = YES; + UIImage *img = nil; + if (@available(iOS 13.0, *)) img = [UIImage systemImageNamed:@"pencil"]; // 铅笔图标 + [_editBadge setImage:img forState:UIControlStateNormal]; + [_editBadge setTitle:(img ? @"" : @"✎") forState:UIControlStateNormal]; + _editBadge.titleLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightBold]; + [_editBadge setTitleColor:UIColor.whiteColor forState:UIControlStateNormal]; + [_editBadge addTarget:self action:@selector(onTapAvatarEdit) forControlEvents:UIControlEventTouchUpInside]; + } + return _editBadge; +} + +- (UILabel *)modifyLabel { + if (!_modifyLabel) { + _modifyLabel = [UILabel new]; + _modifyLabel.text = @"Modify"; + _modifyLabel.textColor = [UIColor blackColor]; + _modifyLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold]; + } + return _modifyLabel; +} + +- (UIView *)footerView { + if (!_footerView) { + CGFloat w = UIScreen.mainScreen.bounds.size.width; + UIView *fv = [[UIView alloc] initWithFrame:CGRectMake(0, 0, w, 120)]; + fv.backgroundColor = UIColor.clearColor; + + [fv addSubview:self.logoutBg]; + [self.logoutBg mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(fv).offset(16); + make.right.equalTo(fv).offset(-16); + make.top.equalTo(fv).offset(14); + make.height.mas_equalTo(56); + }]; + + [self.logoutBg addSubview:self.logoutBtn]; + [self.logoutBtn mas_makeConstraints:^(MASConstraintMaker *make) { + make.edges.equalTo(self.logoutBg); + }]; + + _footerView = fv; + } + return _footerView; +} + +- (UIView *)logoutBg { + if (!_logoutBg) { + _logoutBg = [UIView new]; + _logoutBg.backgroundColor = UIColor.whiteColor; + _logoutBg.layer.cornerRadius = 12; _logoutBg.layer.masksToBounds = YES; + } + return _logoutBg; +} + +- (UIButton *)logoutBtn { + if (!_logoutBtn) { + _logoutBtn = [UIButton buttonWithType:UIButtonTypeSystem]; + [_logoutBtn setTitle:@"Log Out" forState:UIControlStateNormal]; + [_logoutBtn setTitleColor:[UIColor colorWithRed:0.85 green:0.15 blue:0.11 alpha:1.0] forState:UIControlStateNormal]; + _logoutBtn.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold]; + [_logoutBtn addTarget:self action:@selector(onTapLogout) forControlEvents:UIControlEventTouchUpInside]; + } + return _logoutBtn; +} + +@end