242 lines
8.1 KiB
Objective-C
242 lines
8.1 KiB
Objective-C
//
|
||
// HomeRankDetailPopView.m
|
||
// keyBoard
|
||
//
|
||
// Created by Codex on 2025/11/11.
|
||
//
|
||
|
||
@import UIKit;
|
||
#import "HomeRankDetailPopView.h"
|
||
#import <Masonry/Masonry.h>
|
||
|
||
@interface HomeRankDetailPopView ()
|
||
|
||
// 容器卡片(白底圆角)
|
||
@property (nonatomic, strong) UIView *cardView;
|
||
// 头像(圆形,带白色描边)
|
||
@property (nonatomic, strong) UIImageView *avatarView;
|
||
// 标题
|
||
@property (nonatomic, strong) UILabel *titleLabel;
|
||
// 下载人数文案(绿色)
|
||
@property (nonatomic, strong) UILabel *downloadLabel;
|
||
// 内容气泡容器
|
||
@property (nonatomic, strong) UIView *bubbleView;
|
||
// 内容文本
|
||
@property (nonatomic, strong) UILabel *descLabel;
|
||
// 保存按钮
|
||
@property (nonatomic, strong) UIButton *saveButton;
|
||
// 底部关闭按钮(圆形 X)
|
||
@property (nonatomic, strong) UIButton *closeButton;
|
||
|
||
@end
|
||
|
||
@implementation HomeRankDetailPopView
|
||
|
||
- (instancetype)initWithFrame:(CGRect)frame {
|
||
if (self = [super initWithFrame:frame]) {
|
||
self.backgroundColor = UIColor.clearColor; // 由 LSTPopView 提供半透明背景
|
||
[self buildUI];
|
||
[self makeConstraints];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
#pragma mark - Public
|
||
|
||
- (void)configWithAvatar:(UIImage *)avatar
|
||
title:(NSString *)title
|
||
download:(NSString *)download
|
||
desc:(NSString *)desc {
|
||
self.avatarView.image = avatar ?: [self placeholderAvatar];
|
||
self.titleLabel.text = title ?: @"";
|
||
self.downloadLabel.text = download ?: @"";
|
||
self.descLabel.text = desc ?: @"";
|
||
}
|
||
|
||
#pragma mark - Build UI
|
||
|
||
- (void)buildUI {
|
||
// 添加顺序:先卡片,再头像(悬浮于卡片上方),最后底部关闭
|
||
[self addSubview:self.cardView];
|
||
[self addSubview:self.avatarView];
|
||
[self addSubview:self.closeButton];
|
||
|
||
[self.cardView addSubview:self.titleLabel];
|
||
[self.cardView addSubview:self.downloadLabel];
|
||
[self.cardView addSubview:self.bubbleView];
|
||
[self.bubbleView addSubview:self.descLabel];
|
||
[self.cardView addSubview:self.saveButton];
|
||
}
|
||
|
||
- (void)makeConstraints {
|
||
// 说明:将卡片上下各预留出 48 的间距,顶部用于头像悬浮展示,底部用于放置关闭按钮
|
||
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.right.equalTo(self);
|
||
make.top.equalTo(self).offset(KBFit(56));
|
||
make.height.mas_equalTo(KBFit(358));
|
||
// make.bottom.equalTo(self).offset(-72);
|
||
}];
|
||
|
||
[self.avatarView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.centerX.equalTo(self.cardView);
|
||
make.centerY.equalTo(self.cardView.mas_top); // 一半悬浮在卡片外
|
||
make.width.height.mas_equalTo(112);
|
||
}];
|
||
|
||
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.avatarView.mas_bottom).offset(KBFit(13));
|
||
make.centerX.equalTo(self.cardView);
|
||
make.height.mas_equalTo(KBFit(23));
|
||
}];
|
||
|
||
[self.downloadLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.titleLabel.mas_bottom).offset(KBFit(7));
|
||
make.centerX.equalTo(self.cardView);
|
||
make.height.mas_equalTo(KBFit(23));
|
||
}];
|
||
|
||
[self.bubbleView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.downloadLabel.mas_bottom).offset(KBFit(16));
|
||
make.left.equalTo(self.cardView).offset(20);
|
||
make.right.equalTo(self.cardView).offset(-20);
|
||
make.height.mas_equalTo(KBFit(125));
|
||
}];
|
||
|
||
[self.descLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.edges.equalTo(self.bubbleView).insets(UIEdgeInsetsMake(12, 12, 12, 12));
|
||
}];
|
||
|
||
[self.saveButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.equalTo(self.cardView).offset(20);
|
||
make.right.equalTo(self.cardView).offset(-20);
|
||
make.bottom.equalTo(self.cardView).offset(-KBFit(26));
|
||
make.height.mas_equalTo(KBFit(48));
|
||
}];
|
||
|
||
[self.closeButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.cardView.mas_bottom).offset(16);
|
||
make.centerX.equalTo(self.cardView);
|
||
make.width.height.mas_equalTo(36);
|
||
}];
|
||
}
|
||
|
||
#pragma mark - Actions
|
||
|
||
- (void)onTapSave {
|
||
if (self.saveHandler) self.saveHandler();
|
||
}
|
||
|
||
- (void)onTapClose {
|
||
if (self.closeHandler) self.closeHandler();
|
||
}
|
||
|
||
#pragma mark - Helpers
|
||
|
||
- (UIImage *)placeholderAvatar {
|
||
// 简单生成圆形纯色头像占位
|
||
CGSize size = CGSizeMake(96, 96);
|
||
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
|
||
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
||
[[UIColor colorWithRed:0.93 green:0.96 blue:0.99 alpha:1.0] setFill];
|
||
CGContextFillEllipseInRect(ctx, CGRectMake(0, 0, size.width, size.height));
|
||
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
|
||
UIGraphicsEndImageContext();
|
||
return img;
|
||
}
|
||
|
||
#pragma mark - Lazy UI
|
||
|
||
- (UIView *)cardView {
|
||
if (!_cardView) {
|
||
_cardView = [UIView new];
|
||
_cardView.backgroundColor = UIColor.whiteColor;
|
||
_cardView.layer.cornerRadius = 22.0;
|
||
_cardView.layer.masksToBounds = YES;
|
||
}
|
||
return _cardView;
|
||
}
|
||
|
||
- (UIImageView *)avatarView {
|
||
if (!_avatarView) {
|
||
_avatarView = [[UIImageView alloc] init];
|
||
_avatarView.contentMode = UIViewContentModeScaleAspectFill;
|
||
_avatarView.layer.cornerRadius = 56.0;
|
||
_avatarView.layer.masksToBounds = YES;
|
||
// 外环
|
||
_avatarView.layer.borderColor = UIColor.whiteColor.CGColor;
|
||
_avatarView.layer.borderWidth = 4.0;
|
||
_avatarView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
|
||
}
|
||
return _avatarView;
|
||
}
|
||
|
||
- (UILabel *)titleLabel {
|
||
if (!_titleLabel) {
|
||
_titleLabel = [UILabel new];
|
||
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||
_titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
||
_titleLabel.textAlignment = NSTextAlignmentCenter;
|
||
_titleLabel.text = @"High EQ"; // 默认文案
|
||
}
|
||
return _titleLabel;
|
||
}
|
||
|
||
- (UILabel *)downloadLabel {
|
||
if (!_downloadLabel) {
|
||
_downloadLabel = [UILabel new];
|
||
_downloadLabel.textColor = [UIColor colorWithHex:KBColorValue];
|
||
_downloadLabel.backgroundColor = [UIColor colorWithHex:0xEDFFFD];
|
||
_downloadLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightMedium];
|
||
_downloadLabel.textAlignment = NSTextAlignmentCenter;
|
||
_downloadLabel.text = @"Download: 1 Million";
|
||
}
|
||
return _downloadLabel;
|
||
}
|
||
|
||
- (UIView *)bubbleView {
|
||
if (!_bubbleView) {
|
||
_bubbleView = [UIView new];
|
||
_bubbleView.backgroundColor = [UIColor colorWithHex:0xF8F8F8];
|
||
_bubbleView.layer.cornerRadius = 9.0;
|
||
_bubbleView.layer.masksToBounds = YES;
|
||
}
|
||
return _bubbleView;
|
||
}
|
||
|
||
- (UILabel *)descLabel {
|
||
if (!_descLabel) {
|
||
_descLabel = [UILabel new];
|
||
_descLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
||
_descLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightSemibold];
|
||
_descLabel.numberOfLines = 0;
|
||
_descLabel.text = @"Be Neither Too Close\nNor Too Distant";
|
||
}
|
||
return _descLabel;
|
||
}
|
||
|
||
- (UIButton *)saveButton {
|
||
if (!_saveButton) {
|
||
_saveButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||
[_saveButton setTitle:@"Save" forState:UIControlStateNormal];
|
||
[_saveButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
|
||
_saveButton.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightSemibold];
|
||
_saveButton.backgroundColor = [UIColor colorWithRed:0.02 green:0.75 blue:0.67 alpha:1.0];
|
||
_saveButton.layer.cornerRadius = 24.0;
|
||
_saveButton.layer.masksToBounds = YES;
|
||
[_saveButton addTarget:self action:@selector(onTapSave) forControlEvents:UIControlEventTouchUpInside];
|
||
}
|
||
return _saveButton;
|
||
}
|
||
|
||
- (UIButton *)closeButton {
|
||
if (!_closeButton) {
|
||
_closeButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||
[_closeButton setImage:[UIImage imageNamed:@"white_close_icon"] forState:UIControlStateNormal];
|
||
[_closeButton addTarget:self action:@selector(onTapClose) forControlEvents:UIControlEventTouchUpInside];
|
||
}
|
||
return _closeButton;
|
||
}
|
||
|
||
@end
|
||
|