Files
peko-ios/YuMi/Modules/YMMine/View/Medals/MedalsRankViewController.m

522 lines
19 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MedalsRankViewController.m
// YuMi
//
// Created by P on 2025/6/20.
//
#import "MedalsRankViewController.h"
#import "MedalsPresenter.h"
#import "MedalsViewController.h"
#import "UserInfoModel.h"
@interface MedalsRankListCell : UITableViewCell
@property (nonatomic, strong) UILabel *indexLabel;
@property (nonatomic, strong) NetImageView *avatarImageView;
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UILabel *countLabel;
@property (nonatomic, strong) UILabel *detailLabel;
+ (void)registerTo:(UITableView *)tableView;
+ (instancetype)cellFor:(UITableView *)tableView atIndexPath:(NSIndexPath *)index;
- (void)updateCell:(MedalsRankUserModel *)userModel atIndex:(NSInteger)index;
@end
@implementation MedalsRankListCell
+ (NSString *)cellID {
return NSStringFromClass([MedalsRankListCell class]);
}
+ (void)registerTo:(UITableView *)tableView {
[tableView registerClass:[self class] forCellReuseIdentifier:[self cellID]];
}
+ (instancetype)cellFor:(UITableView *)tableView atIndexPath:(NSIndexPath *)index {
MedalsRankListCell *cell = [tableView dequeueReusableCellWithIdentifier:[self cellID] forIndexPath:index];
return cell;
}
- (void)updateCell:(MedalsRankUserModel *)userModel atIndex:(NSInteger)index {
self.avatarImageView.imageUrl = userModel.avatar;
self.nameLabel.text = userModel.nick;
self.indexLabel.text = @(userModel.rank).stringValue;
self.countLabel.text = @(userModel.medalCount).stringValue;
// self.detailLabel.hidden = userModel.uid == 0;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.backgroundColor = [UIColor clearColor];
self.contentView.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
self.indexLabel = [UILabel labelInitWithText:@"" font:kFontMedium(14) textColor:[UIColor whiteColor]];
[self.contentView addSubview:self.indexLabel];
[self.indexLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.contentView);
make.leading.mas_equalTo(18);
}];
NetImageConfig *config = [[NetImageConfig alloc] init];
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
self.avatarImageView = [[NetImageView alloc] initWithConfig:config];
[self.avatarImageView setCornerRadius:47/2];
[self.contentView addSubview:self.avatarImageView];
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.contentView);
make.leading.mas_equalTo(self.indexLabel.mas_trailing).offset(16);
make.size.mas_equalTo(CGSizeMake(47, 47));
}];
self.nameLabel = [UILabel labelInitWithText:@"" font:kFontSemibold(15) textColor:[UIColor whiteColor]];
[self.contentView addSubview:self.nameLabel];
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.avatarImageView.mas_trailing).offset(6);
make.top.mas_equalTo(self.avatarImageView);
}];
UIImageView *rankIcon = [[UIImageView alloc] initWithImage:[kImage(@"medals_icon_rank") ms_SetImageForRTL]];
[self.contentView addSubview:rankIcon];
[rankIcon mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.avatarImageView.mas_trailing).offset(6);
make.bottom.mas_equalTo(self.avatarImageView);
make.size.mas_equalTo(CGSizeMake(15, 15));
}];
self.countLabel = [UILabel labelInitWithText:@"" font:kFontMedium(14) textColor:[UIColor whiteColor]];
[self.contentView addSubview:self.countLabel];
[self.countLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(rankIcon.mas_trailing).offset(6);
make.centerY.mas_equalTo(rankIcon);
}];
self.detailLabel = [UILabel labelInitWithText:YMLocalizedString(@"20.20.61_text_13")
font:kFontRegular(12)
textColor:[UIColor colorWithWhite:1 alpha:0.6]];
[self.contentView addSubview:self.detailLabel];
[self.detailLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.trailing.mas_equalTo(self.contentView).offset(-28);
make.centerY.mas_equalTo(self.contentView);
}];
UIImageView *arrow = [[UIImageView alloc] initWithImage:kImage(@"grey_right_arrow")];
[self.contentView addSubview:arrow];
[arrow mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(self.contentView);
make.trailing.mas_equalTo(self.contentView).offset(-15);
make.size.mas_equalTo(CGSizeMake(15, 15));
}];
}
return self;
}
@end
@interface MedalsRankTopView : UIView
@property (nonatomic, assign) NSInteger topLevel;
@property (nonatomic, strong) MedalsRankUserModel *userModel;
@property (nonatomic, copy) void (^onTapBlock)(MedalsRankUserModel *userModel);
@end
@implementation MedalsRankTopView
{
NetImageView *avataImageView;
UIImageView *decorationImageView;
UILabel *nameLabel;
UILabel *honorLabel;
UIImageView *honorImageView;
UIImageView *medalIconImageView;
UILabel *medalCountLabel;
UIStackView *medalCountStack;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
NetImageConfig *config = [[NetImageConfig alloc] init];
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
avataImageView = [[NetImageView alloc] initWithConfig:config];
[avataImageView setCornerRadius:50];
[self addSubview:avataImageView];
[avataImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(self);
make.size.mas_equalTo(CGSizeMake(100, 100));
}];
decorationImageView = [[UIImageView alloc] init];
[self addSubview:decorationImageView];
[decorationImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
honorImageView = [[UIImageView alloc] initWithImage:kImage(@"medals_rank_namebar")];
[self addSubview:honorImageView];
[honorImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self);
make.bottom.mas_equalTo(self).offset(6);
}];
honorLabel = [UILabel labelInitWithText:YMLocalizedString(@"20.20.61_text_12")
font:kFontSemibold(12)
textColor:UIColorFromRGB(0xfff27b)];
[self addSubview:honorLabel];
[honorLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.mas_equalTo(honorImageView);
}];
nameLabel = [UILabel labelInitWithText:@"" font:kFontSemibold(15) textColor:UIColorFromRGB(0xffffff)];
[self addSubview:nameLabel];
medalIconImageView = [[UIImageView alloc] initWithImage:kImage(@"medals_icon_rank")];
medalCountLabel = [UILabel labelInitWithText:@"0" font:kFontMedium(14) textColor:UIColorFromRGB(0xffffff)];
medalCountStack = [[UIStackView alloc] initWithArrangedSubviews:@[
medalIconImageView,
medalCountLabel
]];
[self addSubview:medalCountStack];
[medalIconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.size.mas_equalTo(CGSizeMake(15, 15));
}];
honorLabel.hidden = YES;
honorImageView.hidden = YES;
// 添加点击手势
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapTopView)];
[self addGestureRecognizer:tapGesture];
self.userInteractionEnabled = YES;
}
return self;
}
- (void)didTapTopView {
if (self.onTapBlock && self.userModel) {
self.onTapBlock(self.userModel);
}
}
- (void)setTopLevel:(NSInteger)topLevel {
_topLevel = topLevel;
NSString *imagePath = @"";
NSInteger nameTopOffset = 0;
NSInteger bottomOffset = 0;
switch (topLevel) {
case 1:
imagePath = @"medals_rank_top_1";
honorLabel.hidden = NO;
honorImageView.hidden = NO;
nameTopOffset = 8;
bottomOffset = 40;
break;
case 2:
imagePath = @"medals_rank_top_2";
nameTopOffset = -4;
bottomOffset = 20;
break;
case 3:
imagePath = @"medals_rank_top_3";
nameTopOffset = -4;
bottomOffset = 20;
break;
default:
break;
}
[nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self);
make.top.mas_equalTo(self.mas_bottom).offset(nameTopOffset);
}];
[medalCountStack mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self);
make.top.mas_equalTo(nameLabel.mas_bottom).offset(4);
}];
if (![NSString isEmpty:imagePath]) {
decorationImageView.image = kImage(imagePath);
}
}
- (void)setUserModel:(MedalsRankUserModel *)userModel {
_userModel = userModel;
if (userModel) {
avataImageView.imageUrl = userModel.avatar;
nameLabel.text = userModel.nick;
medalCountLabel.text = @(userModel.medalCount).stringValue;
}
}
@end
@interface MedalsRankViewController () <MedalsPresenterProtocol, UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) UILabel *indexLabel;
@property (nonatomic, strong) NetImageView *avatarImageView;
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UILabel *countLabel;
@property (nonatomic, strong) MedalsRankTopView *topOne;
@property (nonatomic, strong) MedalsRankTopView *topTwo;
@property (nonatomic, strong) MedalsRankTopView *topThree;
@property (nonatomic, strong) MedalsRankUserModel *mineRankModel;
@property (nonatomic, strong) NSMutableArray <MedalsRankUserModel *>*rankList;
@property (nonatomic, strong) UITableView *rankTableView;
@end
@implementation MedalsRankViewController
- (BOOL)isHiddenNavBar {
return YES;
}
- (MedalsPresenter *)createPresenter {
return [[MedalsPresenter alloc] init];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupUI];
[self loadData];
}
#pragma mark -
- (void)setupUI {
self.view.backgroundColor = UIColorFromRGB(0x1B0043);
[self setupTopArea];
[self setupRankList];
[self setupBottomArea];
[self setupNavigationBar];
}
- (void)setupNavigationBar {
[self setupCustomNavigationBar:^{}
title:YMLocalizedString(@"20.20.61_text_11")
titleColor:[UIColor whiteColor]];
}
- (void)setupTopArea {
UIImageView *topBG = [[UIImageView alloc] initWithImage:kImage(@"medals_rank_top_bg")];
topBG.frame = CGRectMake(0, 0, KScreenWidth, kGetScaleWidth(270));
[self.view addSubview:topBG];
self.topOne = [self rankTopView:1];
self.topTwo = [self rankTopView:2];
self.topThree = [self rankTopView:3];
// 设置点击回调
__weak typeof(self) weakSelf = self;
self.topOne.onTapBlock = ^(MedalsRankUserModel *userModel) {
[weakSelf handleTopViewTap:userModel];
};
self.topTwo.onTapBlock = ^(MedalsRankUserModel *userModel) {
[weakSelf handleTopViewTap:userModel];
};
self.topThree.onTapBlock = ^(MedalsRankUserModel *userModel) {
[weakSelf handleTopViewTap:userModel];
};
[self.view addSubview:self.topOne];
[self.view addSubview:self.topTwo];
[self.view addSubview:self.topThree];
[self.topOne mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.view).offset(95);
make.centerX.mas_equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(209, 145));
}];
[self.topTwo mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(topBG.mas_bottom);
make.leading.mas_equalTo(self.view).offset(25);
make.size.mas_equalTo(CGSizeMake(145, 145));
}];
[self.topThree mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(topBG.mas_bottom);
make.trailing.mas_equalTo(self.view).offset(-25);
make.size.mas_equalTo(CGSizeMake(145, 145));
}];
}
- (void)setupRankList {
[self.view addSubview:self.rankTableView];
CGFloat height = 84;
[self.rankTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.topTwo.mas_bottom).offset(40);
make.bottom.mas_equalTo(self.view).offset(-height);
make.leading.trailing.mas_equalTo(self.view);
}];
}
- (void)setupBottomArea {
CGFloat height = 84;
UIView *bottomArea = [[UIView alloc] initWithFrame:CGRectMake(0, KScreenHeight - height, KScreenWidth, height)];
[bottomArea addGradientBackgroundWithColors:@[
UIColorFromRGB(0x3d1479),
UIColorFromRGB(0x1c0044),
] startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1) cornerRadius:0];
[self.view addSubview:bottomArea];
self.indexLabel = [UILabel labelInitWithText:@"" font:kFontMedium(14) textColor:[UIColor whiteColor]];
[bottomArea addSubview:self.indexLabel];
[self.indexLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(bottomArea);
make.leading.mas_equalTo(18);
}];
NetImageConfig *config = [[NetImageConfig alloc] init];
config.placeHolder = [UIImageConstant defaultAvatarPlaceholder];
self.avatarImageView = [[NetImageView alloc] initWithConfig:config];
[self.avatarImageView setCornerRadius:47/2];
[bottomArea addSubview:self.avatarImageView];
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerY.mas_equalTo(bottomArea);
make.leading.mas_equalTo(self.indexLabel.mas_trailing).offset(16);
make.size.mas_equalTo(CGSizeMake(47, 47));
}];
self.nameLabel = [UILabel labelInitWithText:@"" font:kFontSemibold(15) textColor:[UIColor whiteColor]];
[bottomArea addSubview:self.nameLabel];
[self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.avatarImageView.mas_trailing).offset(6);
make.top.mas_equalTo(self.avatarImageView);
}];
UIImageView *rankIcon = [[UIImageView alloc] initWithImage:kImage(@"medals_rank")];
[bottomArea addSubview:rankIcon];
[rankIcon mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(self.avatarImageView.mas_trailing).offset(6);
make.bottom.mas_equalTo(self.avatarImageView);
make.size.mas_equalTo(CGSizeMake(10, 14));
}];
self.countLabel = [UILabel labelInitWithText:@"" font:kFontMedium(14) textColor:[UIColor whiteColor]];
[bottomArea addSubview:self.countLabel];
[self.countLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.leading.mas_equalTo(rankIcon.mas_trailing).offset(6);
make.centerY.mas_equalTo(rankIcon);
}];
}
#pragma mark -
- (void)loadData {
[self.presenter rankList:1];
}
- (void)rankListSuccess:(MedalsRankModel *)model {
if (model) {
self.mineRankModel = model.mine;
self.avatarImageView.imageUrl = self.mineRankModel.avatar;
self.nameLabel.text = self.mineRankModel.nick;
self.indexLabel.text = @(self.mineRankModel.rank).stringValue;
self.countLabel.text = @(self.mineRankModel.medalCount).stringValue;
self.rankList = [NSMutableArray array];
NSInteger currentRank = 4; // 从第4名开始计算前三名已经处理
for (MedalsRankUserModel *user in model.rankList) {
if (user.rank == 1) {
self.topOne.userModel = user;
} else if (user.rank == 2) {
self.topTwo.userModel = user;
} else if (user.rank == 3) {
self.topThree.userModel = user;
} else {
[self.rankList addObject:user];
currentRank = MAX(currentRank, user.rank + 1);
}
}
// 补充数据至 10 个rankList 中应有 7 个,因为前三名在 top 视图中)
NSInteger targetCount = 7; // 总共10个减去前3名
while (self.rankList.count < targetCount) {
MedalsRankUserModel *emptyUser = [[MedalsRankUserModel alloc] init];
emptyUser.rank = currentRank;
emptyUser.uid = 0;
emptyUser.avatar = @"";
emptyUser.nick = @"--";
emptyUser.medalCount = 0;
[self.rankList addObject:emptyUser];
currentRank++;
}
[self.rankTableView reloadData];
}
}
- (void)rankListFailure {
}
#pragma mark - UITableView DataSource & Delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.rankList.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 70;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MedalsRankListCell *cell = [MedalsRankListCell cellFor:tableView atIndexPath:indexPath];
MedalsRankUserModel *model = [self.rankList xpSafeObjectAtIndex:indexPath.row];
[cell updateCell:model atIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// 取消选中高亮效果
[tableView deselectRowAtIndexPath:indexPath animated:YES];
MedalsRankUserModel *model = [self.rankList xpSafeObjectAtIndex:indexPath.row];
// 检查是否为有效的用户数据(非空补充数据)
if (model && model.uid != 0) {
[self handleTopViewTap:model];
}
}
- (void)handleTopViewTap:(MedalsRankUserModel *)model {
if (model && model.uid != 0) {
UserInfoModel *userInfo = [[UserInfoModel alloc] init];
userInfo.uid = model.uid;
userInfo.avatar = model.avatar;
userInfo.nick = model.nick;
MedalsViewController *vc = [[MedalsViewController alloc] initForOtherMedals:userInfo];
[self.navigationController pushViewController:vc animated:YES];
}
}
#pragma mark -
- (MedalsRankTopView *)rankTopView:(NSInteger)rank {
MedalsRankTopView *topView = [[MedalsRankTopView alloc] initWithFrame:CGRectMake(0, 0, rank == 1 ? 209 : 145, 145)];
topView.topLevel = rank;
return topView;
}
- (UITableView *)rankTableView {
if (!_rankTableView) {
_rankTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_rankTableView.delegate = self;
_rankTableView.dataSource = self;
_rankTableView.backgroundColor = [UIColor clearColor];
[MedalsRankListCell registerTo:_rankTableView];
}
return _rankTableView;
}
@end