添加弹窗

This commit is contained in:
2025-11-11 14:38:38 +08:00
parent e4ba237a00
commit 57bd4ba109
8 changed files with 338 additions and 8 deletions

View File

@@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "white_close_icon@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "white_close_icon@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,29 @@
//
// HomeRankDetailPopView.h
// keyBoard
//
// Created by Codex on 2025/11/11.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/// 排行榜详情弹窗的自定义内容视图(给 LSTPopView 使用)
@interface HomeRankDetailPopView : UIView
/// 保存按钮点击回调
@property (nonatomic, copy, nullable) void (^saveHandler)(void);
/// 关闭按钮点击回调(底部圆形 X
@property (nonatomic, copy, nullable) void (^closeHandler)(void);
/// 配置数据
- (void)configWithAvatar:(UIImage *_Nullable)avatar
title:(NSString *)title
download:(NSString *)download
desc:(NSString *)desc;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,241 @@
//
// 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

View File

@@ -7,6 +7,8 @@
@import UIKit;
#import "HomeRankContentVC.h"
#import "HomeRankDetailPopView.h" //
#import "LSTPopView.h" // LSTPopView
// Cell
#import "HomeRankCardCell.h"
@@ -92,16 +94,44 @@
#pragma mark - UICollectionViewDelegateFlowLayout
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat totalHInset = 16 + 16; // section i/l/r
CGFloat spacing = 16; // interitem spacing
CGFloat w = collectionView.bounds.size.width - totalHInset; // not including section insets yet
// Two columns each width = (width - spacing - lr insets)/2
CGFloat totalHInset = 16 + 16;
CGFloat spacing = 16;
CGFloat w = collectionView.bounds.size.width - totalHInset;
CGFloat cellWidth = (w - spacing) / 2.0;
//
CGFloat cellHeight = 234.0;
return CGSizeMake(floor(cellWidth), cellHeight);
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
// ->
NSDictionary *d = self.dataSource[indexPath.item];
//
CGFloat width = MIN(KB_SCREEN_WIDTH - 76, 420);
HomeRankDetailPopView *content = [[HomeRankDetailPopView alloc] initWithFrame:CGRectMake(0, 0, width, 460)];
NSString *title = d[@"title"] ?: @"High EQ";
NSString *people = d[@"people"] ?: @"Download: 1 Million";
NSString *desc = @"Be Neither Too Close\nNor Too Distant"; //
[content configWithAvatar:nil title:title download:people desc:desc];
//
LSTPopView *pop = [LSTPopView initWithCustomView:content
parentView:nil
popStyle:LSTPopStyleScale
dismissStyle:LSTDismissStyleScale];
pop.hemStyle = LSTHemStyleCenter; //
pop.bgColor = [[UIColor blackColor] colorWithAlphaComponent:0.4];
pop.isClickBgDismiss = YES; //
pop.cornerRadius = 0; // view
__weak typeof(pop) weakPop = pop;
content.saveHandler = ^{ [weakPop dismiss]; };
content.closeHandler = ^{ [weakPop dismiss]; };
[pop pop];
}
#pragma mark - JXCategoryListContentViewDelegate
- (UIView *)listView {

View File

@@ -57,8 +57,10 @@
#define KB_TABBAR_BASE_HEIGHT 49.0
#define COLOR_WITH_RGB(R,G,B,A) [UIColor colorWithRed:R green:G blue:B alpha:A]
/// 主题色 绿色
#define KBColorValue 0x02BEAC
/// 通用黑色
#define KBBlackValue 0x1B1F1A
// 当前 KeyWindowiOS 13 场景化兼容)
static inline UIWindow *KB_KeyWindow(void) {