新增勋章相关的 UI 组件,包括 MedalsWearingViewController、MedalsWearingControlCollectionViewCell 和 MedalsWearingListCollectionViewCell,更新相关逻辑以支持勋章的使用状态管理和展示,保持代码结构一致性。

This commit is contained in:
edwinQQQ
2025-06-19 19:22:56 +08:00
parent da8d88347e
commit 4c76813273
27 changed files with 814 additions and 21 deletions

View File

@@ -488,6 +488,7 @@
4C0A5B842E02675300955219 /* MedalsCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A5B832E02675300955219 /* MedalsCollectionViewCell.m */; };
4C0A5B872E02BB1100955219 /* MedalsLevelIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A5B862E02BB1100955219 /* MedalsLevelIndicatorView.m */; };
4C0A5B8A2E02BC3900955219 /* MedalsDetailView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A5B892E02BC3900955219 /* MedalsDetailView.m */; };
4C0A5B902E03EF4B00955219 /* MedalsWearingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C0A5B8F2E03EF4B00955219 /* MedalsWearingViewController.m */; };
4C1064882E0014CF007E1586 /* NSMutableArray+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1064872E0014CF007E1586 /* NSMutableArray+Safe.m */; };
4C1119722DD7218300C18416 /* MyEventsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1119712DD7218300C18416 /* MyEventsViewController.m */; };
4C1392932D6D963700A6DFB5 /* SubRechargersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1392922D6D963600A6DFB5 /* SubRechargersViewController.m */; };
@@ -578,6 +579,8 @@
4CEB9EAD2D09AA0400443480 /* SexAgeLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CEB9EAC2D09AA0400443480 /* SexAgeLabel.m */; };
4CEB9EB02D0AF4FE00443480 /* TwentyMicStageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CEB9EAF2D0AF4FE00443480 /* TwentyMicStageView.m */; };
4CEB9EB32D0AFCE200443480 /* NineteenMicStageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CEB9EB22D0AFCE200443480 /* NineteenMicStageView.m */; };
4CF3CE2B2E0403500071101F /* MedalsWearingControlCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CF3CE2A2E0403500071101F /* MedalsWearingControlCollectionViewCell.m */; };
4CF3CE2E2E040EEC0071101F /* MedalsWearingListCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CF3CE2D2E040EEC0071101F /* MedalsWearingListCollectionViewCell.m */; };
4CF67BA52DF9568C00EE5A28 /* BaseModelVo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CF67BA42DF9568C00EE5A28 /* BaseModelVo.m */; };
4CFBE0CA2DAD085700A923AF /* BravoGiftTabInfomationModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFBE0C92DAD085700A923AF /* BravoGiftTabInfomationModel.m */; };
4CFBE0CD2DAD0FC400A923AF /* PIGiftBravoGiftBroadcastView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CFBE0CC2DAD0FC400A923AF /* PIGiftBravoGiftBroadcastView.m */; };
@@ -2643,6 +2646,8 @@
4C0A5B862E02BB1100955219 /* MedalsLevelIndicatorView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MedalsLevelIndicatorView.m; sourceTree = "<group>"; };
4C0A5B882E02BC3900955219 /* MedalsDetailView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MedalsDetailView.h; sourceTree = "<group>"; };
4C0A5B892E02BC3900955219 /* MedalsDetailView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MedalsDetailView.m; sourceTree = "<group>"; };
4C0A5B8E2E03EF4B00955219 /* MedalsWearingViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MedalsWearingViewController.h; sourceTree = "<group>"; };
4C0A5B8F2E03EF4B00955219 /* MedalsWearingViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MedalsWearingViewController.m; sourceTree = "<group>"; };
4C1064862E0014CF007E1586 /* NSMutableArray+Safe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+Safe.h"; sourceTree = "<group>"; };
4C1064872E0014CF007E1586 /* NSMutableArray+Safe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+Safe.m"; sourceTree = "<group>"; };
4C1119702DD7218300C18416 /* MyEventsViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MyEventsViewController.h; sourceTree = "<group>"; };
@@ -2815,6 +2820,10 @@
4CEB9EAF2D0AF4FE00443480 /* TwentyMicStageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TwentyMicStageView.m; sourceTree = "<group>"; };
4CEB9EB12D0AFCE200443480 /* NineteenMicStageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NineteenMicStageView.h; sourceTree = "<group>"; };
4CEB9EB22D0AFCE200443480 /* NineteenMicStageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NineteenMicStageView.m; sourceTree = "<group>"; };
4CF3CE292E0403500071101F /* MedalsWearingControlCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MedalsWearingControlCollectionViewCell.h; sourceTree = "<group>"; };
4CF3CE2A2E0403500071101F /* MedalsWearingControlCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MedalsWearingControlCollectionViewCell.m; sourceTree = "<group>"; };
4CF3CE2C2E040EEC0071101F /* MedalsWearingListCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MedalsWearingListCollectionViewCell.h; sourceTree = "<group>"; };
4CF3CE2D2E040EEC0071101F /* MedalsWearingListCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MedalsWearingListCollectionViewCell.m; sourceTree = "<group>"; };
4CF67BA32DF9568C00EE5A28 /* BaseModelVo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseModelVo.h; sourceTree = "<group>"; };
4CF67BA42DF9568C00EE5A28 /* BaseModelVo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BaseModelVo.m; sourceTree = "<group>"; };
4CFBE0C82DAD085700A923AF /* BravoGiftTabInfomationModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BravoGiftTabInfomationModel.h; sourceTree = "<group>"; };
@@ -6858,6 +6867,12 @@
4C0A5B862E02BB1100955219 /* MedalsLevelIndicatorView.m */,
4C0A5B882E02BC3900955219 /* MedalsDetailView.h */,
4C0A5B892E02BC3900955219 /* MedalsDetailView.m */,
4C0A5B8E2E03EF4B00955219 /* MedalsWearingViewController.h */,
4C0A5B8F2E03EF4B00955219 /* MedalsWearingViewController.m */,
4CF3CE292E0403500071101F /* MedalsWearingControlCollectionViewCell.h */,
4CF3CE2A2E0403500071101F /* MedalsWearingControlCollectionViewCell.m */,
4CF3CE2C2E040EEC0071101F /* MedalsWearingListCollectionViewCell.h */,
4CF3CE2D2E040EEC0071101F /* MedalsWearingListCollectionViewCell.m */,
);
path = Medals;
sourceTree = "<group>";
@@ -12156,6 +12171,7 @@
E84CBCE72843807500D43221 /* XPMineFriendPresenter.m in Sources */,
E82D5C7D276B343300858D6D /* YYAnimatedImageView+ImageShow.m in Sources */,
E80E09B32A42071D00CD2BE7 /* XPRoomStarKitchenBannerView.m in Sources */,
4CF3CE2B2E0403500071101F /* MedalsWearingControlCollectionViewCell.m in Sources */,
E8B846C726FDB45000A777FE /* XPMineUserInfoAlbumProtocol.h in Sources */,
9B1EF3D527E8294B00554295 /* XPMineDressEmptyCollectionViewCell.m in Sources */,
4CFBE0CD2DAD0FC400A923AF /* PIGiftBravoGiftBroadcastView.m in Sources */,
@@ -12859,6 +12875,7 @@
237700DA2BC7D5EC00D661F1 /* UILabel+MSRTL.m in Sources */,
E8A30BEE28534AB1003B4873 /* XPSessionFindNewPresenter.m in Sources */,
9BDA3E7727FD41C200517FE6 /* XPAnchorFansTeamViewController.m in Sources */,
4C0A5B902E03EF4B00955219 /* MedalsWearingViewController.m in Sources */,
23E9EAAD2A84C9B800B792F2 /* XPMineUserInfoTagItemView.m in Sources */,
18A61BE8274F9CF000A09A54 /* SessionListViewController.m in Sources */,
E8C1CD6A27D8937800376F83 /* XPRoomFaceCollectionViewCell.m in Sources */,
@@ -13361,6 +13378,7 @@
E80EC81328ACD84000D133C5 /* QKeyboardManager.m in Sources */,
4CD6FF692D673F7F00262AB7 /* AgentMessageTableViewCell.m in Sources */,
4C1392962D6DA22B00A6DFB5 /* RechargerTransferHistoryViewController.m in Sources */,
4CF3CE2E2E040EEC0071101F /* MedalsWearingListCollectionViewCell.m in Sources */,
E87DF4B32A429C6E009C1185 /* FirstChargeRoomWindowModel.m in Sources */,
E8AC722126F47E23007D6E91 /* XPMineAboutUsViewController.m in Sources */,
E8E21A9E28B4DFE8008F7C9D /* XPSailingBuyFuelView.m in Sources */,

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -9,7 +9,7 @@
NS_ASSUME_NONNULL_BEGIN
@interface MedalVos : PIBaseModel
@interface MedalVo : PIBaseModel
@property (nonatomic, assign) NSInteger expireSeconds;
@property (nonatomic, assign) BOOL hasGain;
@@ -28,7 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) NSInteger medalLevel;
@property (nonatomic, copy) NSString *seriesName;
@property (nonatomic, copy) NSArray <MedalVos *> *medalVos;
@property (nonatomic, copy) NSArray <MedalVo *> *medalVos;
@end
@@ -49,6 +49,20 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy) NSArray *useMedals;
@end
@interface VipMedalSeatVo : PIBaseModel
@property (nonatomic, assign) NSInteger medalSeatNum;
@property (nonatomic, assign) NSInteger vipLevel;
@end
@interface MineAllMedalModel : PIBaseModel
@property (nonatomic, copy) NSArray <MedalVo *> *allMedals;
@property (nonatomic, copy) NSArray <VipMedalSeatVo *>*vipMedalSeatVos;
@property (nonatomic, copy) NSArray *useMedals;
@property (nonatomic, assign) NSInteger vipLevel;
@property (nonatomic, assign) NSInteger medalNum;
@end
@interface MedalsModel : PIBaseModel
@end

View File

@@ -7,14 +7,14 @@
#import "MedalsModel.h"
@implementation MedalVos
@implementation MedalVo
@end
@implementation MedalSeriesItemVo
+ (NSDictionary *)mj_objectClassInArray {
return @{
@"medalVos" : [MedalVos class]
@"medalVos" : [MedalVo class]
};
}
@end
@@ -35,6 +35,22 @@
}
@end
@implementation VipMedalSeatVo
@end
@implementation MineAllMedalModel
+ (NSDictionary *)mj_objectClassInArray {
return @{
@"allMedals" : [MedalVo class],
@"vipMedalSeatVos" : [VipMedalSeatVo class],
// @"allMedals" : [MedalVo class],
};
}
@end
@implementation MedalsModel
@end

View File

@@ -14,13 +14,19 @@ NS_ASSUME_NONNULL_BEGIN
- (void)userMedalsSuccess:(UserMedalsModel *)userMedalsModel;
- (void)userMedalsFailure;
- (void)squareMedalsSuccess:(UserMedalsModel *)userMedalsModel;
- (void)squareMedalsSuccess:(NSArray <MedalSeriesVo *> *)squareMedalsModel;
- (void)squareMedalsFailure;
@optional
- (void)mineAllMedalsSuccess:(MineAllMedalModel *)model;
- (void)mineAllMedalsFailure;
@end
@interface MedalsPresenter : BaseMvpPresenter
- (NSInteger)pageSize;
/// 我的勋章页面(主/客态通用)
/// - Parameters:
/// - uid: 用户uid
@@ -37,6 +43,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)squareMedals:(NSInteger)page
type:(NSInteger)type;
- (void)mineAllMedals:(NSInteger)page;
- (void)updateMedalUseStatus:(NSString *)medalId isUse:(BOOL)isUse;
@end
NS_ASSUME_NONNULL_END

View File

@@ -10,6 +10,10 @@
@implementation MedalsPresenter
- (NSInteger)pageSize {
return 8;
}
- (void)userMedals:(NSInteger)uid page:(NSInteger)page type:(NSInteger)type {
@kWeakify(self);
[Api medalMine:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
@@ -24,7 +28,7 @@
[[self getView] userMedalsFailure];
}
} showLoading:YES errorToast:YES]
pageNo:@(page) pageSize:@(8) uid:@(uid) type:@(type)];
pageNo:@(page) pageSize:@([self pageSize]) uid:@(uid) type:@(type)];
}
- (void)squareMedals:(NSInteger)page type:(NSInteger)type {
@@ -32,7 +36,7 @@
[Api medalSquare:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
@kStrongify(self);
if ([[self getView] respondsToSelector:@selector(squareMedalsSuccess:)]) {
UserMedalsModel *m = [UserMedalsModel modelWithJSON:data.data];
NSArray *m = [MedalSeriesVo modelsWithArray:data.data];
[[self getView] squareMedalsSuccess:m];
}
} fail:^(NSInteger code, NSString * _Nullable msg) {
@@ -41,7 +45,29 @@
[[self getView] squareMedalsFailure];
}
} showLoading:YES errorToast:YES]
pageNo:@(page) pageSize:@(8) type:@(type)];
pageNo:@(page) pageSize:@([self pageSize]) type:@(type)];
}
- (void)mineAllMedals:(NSInteger)page {
[Api medalMineAll:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
if ([[self getView] respondsToSelector:@selector(mineAllMedalsSuccess:)]) {
MineAllMedalModel *m = [MineAllMedalModel modelWithJSON:data.data];
[[self getView] mineAllMedalsSuccess:m];
}
} fail:^(NSInteger code, NSString * _Nullable msg) {
if ([[self getView] respondsToSelector:@selector(mineAllMedalsFailure)]) {
[[self getView] mineAllMedalsFailure];
}
} showLoading:YES errorToast:YES] pageNo:@(page) pageSize:@([self pageSize])];
}
- (void)updateMedalUseStatus:(NSString *)medalId
isUse:(BOOL)isUse {
[Api medalUseMedal:[self createHttpCompletion:^(BaseModel * _Nonnull data) {
} fail:^(NSInteger code, NSString * _Nullable msg) {
} showLoading:YES errorToast:YES] id:medalId useStatus:@(isUse == YES ? 1 : 0)];
}
@end

View File

@@ -24,7 +24,7 @@
@property (nonatomic, strong) UILabel *subLabel;
@property (nonatomic, strong) MedalsLevelIndicatorView *levelIndicatorView;
@property (nonatomic, strong) MedalVos *displayModel;
@property (nonatomic, strong) MedalVo *displayModel;
@property (nonatomic, strong) MedalSeriesItemVo *currentItemVo;
@property (nonatomic, assign) BOOL isVisible; // cell
@@ -69,7 +69,7 @@
make.height.mas_equalTo(self.imageView.mas_width);
}];
[self addSubview:self.mp4View];
[self.contentView addSubview:self.mp4View];
[self.mp4View mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.imageView);
}];
@@ -107,7 +107,7 @@
@kStrongify(self);
//
if (self.currentItemVo && level <= self.currentItemVo.medalVos.count) {
MedalVos *selectedMedalVo = [self.currentItemVo.medalVos xpSafeObjectAtIndex:level - 1];
MedalVo *selectedMedalVo = [self.currentItemVo.medalVos xpSafeObjectAtIndex:level - 1];
if (selectedMedalVo) {
self.displayModel = selectedMedalVo;
[self updateDisplayWithCurrentModel];
@@ -174,7 +174,7 @@
//
for (NSInteger i = 0; i < itemVos.medalVos.count; i++) {
MedalVos *medalVo = [itemVos.medalVos xpSafeObjectAtIndex:i];
MedalVo *medalVo = [itemVos.medalVos xpSafeObjectAtIndex:i];
if (medalVo) {
[self.levelIndicatorView setImageUrl:medalVo.picUrl forLevel:i + 1];
}

View File

@@ -24,7 +24,7 @@
@property (nonatomic, strong) MedalsLevelIndicatorView *levelIndicatorView;
@property (nonatomic, strong) MedalSeriesItemVo *currentSeriesItemVO;
@property (nonatomic, strong) MedalVos *displayModel;
@property (nonatomic, strong) MedalVo *displayModel;
@end
@@ -96,7 +96,7 @@
@kStrongify(self);
//
if (self.currentSeriesItemVO && level <= self.currentSeriesItemVO.medalVos.count) {
MedalVos *selectedMedalVo = [self.currentSeriesItemVO.medalVos xpSafeObjectAtIndex:level - 1];
MedalVo *selectedMedalVo = [self.currentSeriesItemVO.medalVos xpSafeObjectAtIndex:level - 1];
if (selectedMedalVo) {
self.displayModel = selectedMedalVo;
[self updateDisplayWithCurrentModel];
@@ -131,7 +131,7 @@
//
for (NSInteger i = 0; i < self.currentSeriesItemVO.medalVos.count; i++) {
MedalVos *medalVo = [self.currentSeriesItemVO.medalVos xpSafeObjectAtIndex:i];
MedalVo *medalVo = [self.currentSeriesItemVO.medalVos xpSafeObjectAtIndex:i];
if (medalVo) {
[self.levelIndicatorView setImageUrl:medalVo.picUrl forLevel:i + 1];
}

View File

@@ -222,7 +222,7 @@
CGFloat itemWidth = 25.0; //
// 20
CGFloat availableWidth = self.bounds.size.width - 40.0; // 20
CGFloat availableWidth = self.bounds.size.width;// - 40.0; // 20
//
CGFloat spacing = 0;
@@ -281,7 +281,7 @@
if (_maxLevel > 0 && _levelItems.count > 0) {
// 20
CGFloat itemWidth = 25.0;
CGFloat availableWidth = self.bounds.size.width - 40.0; // 20
CGFloat availableWidth = self.bounds.size.width;// - 40.0; // 20
//
CGFloat spacing = 0;
@@ -407,4 +407,24 @@
}
}
//
- (void)calculateLayoutParams:(CGFloat *)itemWidth spacing:(CGFloat *)spacing startX:(CGFloat *)startX forMaxLevel:(NSInteger)maxLevel {
*itemWidth = 25.0; //
//
CGFloat availableWidth = self.bounds.size.width;
//
*spacing = 0;
if (maxLevel > 1) {
*spacing = (availableWidth - (*itemWidth) * maxLevel) / (maxLevel - 1);
}
//
*spacing = MAX(*spacing, 10.0);
// 20
*startX = 20.0;
}
@end

View File

@@ -11,6 +11,7 @@
#import "TYCyclePagerView.h"
#import "MedalsCollectionViewCell.h"
#import "MedalsDetailView.h"
#import "MedalsWearingViewController.h"
typedef enum : NSInteger {
MedalsCenterTab_TaskMedals = 1,
@@ -282,16 +283,16 @@ typedef enum : NSInteger {
[self _updateDataSource:@[]];
}
- (void)squareMedalsSuccess:(UserMedalsModel *)userMedalsModel {
- (void)squareMedalsSuccess:(NSArray <MedalSeriesVo *>*)squareMedalsModel {
[self endReresh];
[self _updateDataSource:userMedalsModel.medalSeries];
[self _updateDataSource:squareMedalsModel];
}
- (void)squareMedalsFailure {
[self endReresh];
}
- (void)_updateDataSource:(NSArray *)models {
- (void)_updateDataSource:(NSArray <MedalSeriesVo *>*)models {
if (models.count < 8) {
[self.medalsCollectionView.mj_footer endRefreshingWithNoMoreData];
@@ -341,7 +342,9 @@ typedef enum : NSInteger {
}
- (void)didTapWearingButton:(UIButton *)sender {
MedalsWearingViewController *vc = [[MedalsWearingViewController alloc] init];
[self addChildViewController:vc];
[self.view addSubview:vc.view];
}
- (void)didTapEmptyMedalButton:(UIButton *)sender {

View File

@@ -0,0 +1,21 @@
//
// MedalsWearingControlCollectionViewCell.h
// YuMi
//
// Created by P on 2025/6/19.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface MedalsWearingControlCollectionViewCell : UICollectionViewCell
+ (void)registerTo:(UICollectionView *)collectionView;
+ (instancetype)cellFor:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)index;
- (void)updateVIPLevel:(NSInteger)level;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,76 @@
//
// MedalsWearingControlCollectionViewCell.m
// YuMi
//
// Created by P on 2025/6/19.
//
#import "MedalsWearingControlCollectionViewCell.h"
@interface MedalsWearingControlCollectionViewCell ()
@property (nonatomic, strong) NetImageView *medalImageView;
@property (nonatomic, strong) UIImageView *vipImageView;
@end
@implementation MedalsWearingControlCollectionViewCell
+ (NSString *)cellID {
return NSStringFromClass([MedalsWearingControlCollectionViewCell class]);
}
+ (void)registerTo:(UICollectionView *)collectionView {
[collectionView registerClass:[self class] forCellWithReuseIdentifier:[self cellID]];
}
+ (instancetype)cellFor:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)index {
MedalsWearingControlCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[self cellID]
forIndexPath:index];
return cell;
}
- (void)updateVIPLevel:(NSInteger)level {
self.vipImageView.hidden = level < 1;
NSString *imagePath = [NSString stringWithFormat:@"medals_control_vip%@",
@(level)];
self.vipImageView.image = kImage(imagePath);
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self.contentView addSubview:self.medalImageView];
[self.contentView addSubview:self.vipImageView];
[self.medalImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.contentView);
}];
[self.vipImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.contentView);
make.centerY.mas_equalTo(self.contentView.mas_bottom);
make.size.mas_equalTo(CGSizeMake(32, 13));
}];
}
return self;
}
#pragma mark -
- (NetImageView *)medalImageView {
if (!_medalImageView) {
NetImageConfig *config = [[NetImageConfig alloc] init];
config.placeHolder = kImage(@"medals_control_position");
_medalImageView = [[NetImageView alloc] initWithConfig:config];
}
return _medalImageView;
}
- (UIImageView *)vipImageView {
if (!_vipImageView) {
_vipImageView = [[UIImageView alloc] init];
}
return _vipImageView;
}
@end

View File

@@ -0,0 +1,21 @@
//
// MedalsWearingListCollectionViewCell.h
// YuMi
//
// Created by P on 2025/6/19.
//
#import <UIKit/UIKit.h>
@class MedalVo;
NS_ASSUME_NONNULL_BEGIN
@interface MedalsWearingListCollectionViewCell : UICollectionViewCell
+ (void)registerTo:(UICollectionView *)collectionView;
+ (instancetype)cellFor:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)index;
- (void)updateCell:(MedalVo *)medalModel;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,191 @@
//
// MedalsWearingListCollectionViewCell.m
// YuMi
//
// Created by P on 2025/6/19.
//
#import "MedalsWearingListCollectionViewCell.h"
#import <QGVAPWrapView.h>
#import "XPRoomGiftAnimationParser.h"
#import "MedalsModel.h"
@interface MedalsWearingListCollectionViewCell ()
@property(nonatomic, copy) NSString *imagePath;
@property(nonatomic, copy) NSString *mp4Path;
@property(nonatomic, strong) NetImageView *imageView;
@property(nonatomic, strong) VAPView *mp4View;
@property(nonatomic, strong) XPRoomGiftAnimationParser *mp4Parser;
@property (nonatomic, strong) UIImageView *selectedImageView;
@property (nonatomic, assign) BOOL isVisible; // cell
@end
@implementation MedalsWearingListCollectionViewCell
+ (NSString *)cellID {
return NSStringFromClass([MedalsWearingListCollectionViewCell class]);
}
+ (void)registerTo:(UICollectionView *)collectionView {
[collectionView registerClass:[self class] forCellWithReuseIdentifier:[self cellID]];
}
+ (instancetype)cellFor:(UICollectionView *)collectionView atIndexPath:(NSIndexPath *)index {
MedalsWearingListCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[self cellID]
forIndexPath:index];
cell.isVisible = YES;
return cell;
}
- (void)updateCell:(MedalVo *)medalModel {
self.selectedImageView.hidden = medalModel.useStatus==NO;
if ([medalModel.picUrl hasSuffix:@"mp4"]) {
[self setMp4Path:medalModel.picUrl];
} else {
[self setImagePath:medalModel.picUrl];
}
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setupUI];
}
return self;
}
- (void)setupUI {
[self.contentView addGradientBackgroundWithColors:@[
UIColorFromRGB(0x41007b),
UIColorFromRGB(0x290858)
] startPoint:CGPointMake(0.5, 0) endPoint:CGPointMake(0.5, 1) cornerRadius:8];
[self.contentView setAllCornerRadius:8
borderWidth:1
borderColor:UIColorFromRGB(0xa166bf)];
self.imageView = [[NetImageView alloc] init];
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
[self.contentView addSubview:self.imageView];
[self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.contentView);
make.top.mas_equalTo(13);
make.leading.trailing.mas_equalTo(self.contentView).inset(13);
make.height.mas_equalTo(self.imageView.mas_width);
}];
[self.contentView addSubview:self.mp4View];
[self.mp4View mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.imageView);
}];
[self.contentView addSubview:self.selectedImageView];
[self.selectedImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(7);
make.trailing.mas_equalTo(-7);
make.size.mas_equalTo(CGSizeMake(21, 21));
}];
}
- (void)setImagePath:(NSString *)imagePath {
// mp4
[self stopMP4Playback];
_imagePath = imagePath;
self.mp4View.hidden = YES;
self.imageView.hidden = NO;
self.imageView.imageUrl = imagePath;
}
- (void)setMp4Path:(NSString *)mp4Path {
// mp4
if ([_mp4Path isEqualToString:mp4Path]) {
return;
}
// mp4
[self stopMP4Playback];
_mp4Path = mp4Path;
self.mp4View.hidden = NO;
self.imageView.hidden = YES;
if (!_mp4Parser) {
self.mp4Parser = [[XPRoomGiftAnimationParser alloc] init];
}
@kWeakify(self);
[self.mp4Parser parseWithURL:mp4Path
completionBlock:^(NSString * _Nullable videoUrl) {
@kStrongify(self);
if (![NSString isEmpty:videoUrl]) {
// cell
if (self.isVisible) {
[self.mp4View playHWDMP4:videoUrl repeatCount:-1 delegate:nil];
} else {
// URL
self.mp4View.tag = 1; //
}
}
} failureBlock:^(NSError * _Nullable error) {
NSLog(@"Failed to parse mp4: %@", error);
}];
}
#pragma mark - MP4
- (void)stopMP4Playback {
if (self.mp4View) {
[self.mp4View stopHWDMP4];
self.mp4View.tag = 0; //
}
}
- (void)pauseMP4Playback {
if (self.mp4View && !self.mp4View.hidden) {
[self.mp4View pauseHWDMP4];
}
}
- (void)resumeMP4Playback {
if (self.mp4View && !self.mp4View.hidden && self.mp4Path) {
if (self.mp4View.tag == 1) { //
@kWeakify(self);
[self.mp4Parser parseWithURL:self.mp4Path
completionBlock:^(NSString * _Nullable videoUrl) {
@kStrongify(self);
if (![NSString isEmpty:videoUrl] && self.isVisible) {
[self.mp4View playHWDMP4:videoUrl repeatCount:-1 delegate:nil];
}
} failureBlock:nil];
} else {
[self.mp4View resumeHWDMP4];
}
}
}
#pragma mark -
- (VAPView *)mp4View {
if (!_mp4View) {
_mp4View = [[VAPView alloc] init];
_mp4View.contentMode = UIViewContentModeScaleAspectFit;
}
return _mp4View;
}
- (UIImageView *)selectedImageView {
if (!_selectedImageView) {
_selectedImageView = [[UIImageView alloc] initWithImage:kImage(@"medals_selected")];
_selectedImageView.hidden = YES;
#if DEBUG
_selectedImageView.hidden = NO;
#endif
}
return _selectedImageView;
}
@end

View File

@@ -0,0 +1,16 @@
//
// MedalsWearingViewController.h
// YuMi
//
// Created by P on 2025/6/19.
//
#import "MvpViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface MedalsWearingViewController : MvpViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,235 @@
//
// MedalsWearingViewController.m
// YuMi
//
// Created by P on 2025/6/19.
//
#import "MedalsWearingViewController.h"
#import "MedalsPresenter.h"
#import "MedalsWearingListCollectionViewCell.h"
#import "MedalsWearingControlCollectionViewCell.h"
#import "MJRefresh.h"
@interface MedalsWearingViewController () <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>
@property (nonatomic, strong) UIView *dismissArea;
@property (nonatomic, strong) UIView *contentArea;
@property (nonatomic, strong) UIImageView *controlAreaBG;
@property (nonatomic, strong) UICollectionView *controlAreaCollectionView;
@property (nonatomic, strong) UICollectionView *medalsAreaCollectionView;
@property (nonatomic, assign) NSInteger medalsAreaPage;
@property (nonatomic, copy) NSArray <MedalVo *> *allMedalsVo;
@property (nonatomic, copy) NSArray <VipMedalSeatVo *> *vipSeatVo;
//@property (nonatomic, copy) NSArray <VipMedalSeatVo *> *vipSeatVo;
@end
@implementation MedalsWearingViewController
- (MedalsPresenter *)createPresenter {
return [[MedalsPresenter alloc] init];
}
- (BOOL)isHiddenNavBar {
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.medalsAreaPage = 1;
[self setupUI];
[self setupRefresh];
[self loadMedals];
}
- (void)setupUI {
self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
[self.view addSubview:self.dismissArea];
[self.view addSubview:self.contentArea];
[self.contentArea addSubview:self.controlAreaBG];
[self.contentArea addSubview:self.controlAreaCollectionView];
[self.controlAreaBG mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(46);
make.leading.trailing.mas_equalTo(self.contentArea).inset(14);
make.height.mas_equalTo(kGetScaleWidth(147));
}];
[self.controlAreaCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self.controlAreaBG);
}];
[self.contentArea addSubview:self.medalsAreaCollectionView];
[self.medalsAreaCollectionView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(self.controlAreaCollectionView.mas_bottom).offset(14);
make.leading.trailing.mas_equalTo(self.controlAreaCollectionView);
make.bottom.mas_equalTo(self.contentArea);
}];
}
- (void)setupRefresh {
MJRefreshNormalHeader *header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(headerRefresh)];
header.lastUpdatedTimeLabel.hidden = YES;
header.stateLabel.hidden = YES;
self.medalsAreaCollectionView.mj_header = header;
MJRefreshBackNormalFooter *footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footerRefresh)];
self.medalsAreaCollectionView.mj_footer = footer;
}
- (void)loadMedals {
[self.presenter mineAllMedals:self.medalsAreaPage];
}
#pragma mark - User Actions
- (void)handleTapGesture:(id)sender {
[self.view removeFromSuperview];
[self removeFromParentViewController];
}
#pragma mark -
- (void)mineAllMedalsSuccess:(MineAllMedalModel *)model {
[self endRefresh];
self.vipSeatVo = model.vipMedalSeatVos;
self.allMedalsVo = model.allMedals;
[self.controlAreaCollectionView reloadData];
[self.medalsAreaCollectionView reloadData];
}
- (void)mineAllMedalsFailure {
[self endRefresh];
// 退
if (self.medalsAreaPage > 1) {
self.medalsAreaPage--;
}
}
- (void)endRefresh {
[self.medalsAreaCollectionView.mj_header endRefreshing];
[self.medalsAreaCollectionView.mj_footer endRefreshing];
}
#pragma mark -
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (collectionView == self.controlAreaCollectionView) {
return 10;
} else if (collectionView == self.medalsAreaCollectionView) {
return self.allMedalsVo.count;
}
return 0;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if (collectionView == self.controlAreaCollectionView) {
MedalsWearingControlCollectionViewCell *cell = [MedalsWearingControlCollectionViewCell cellFor:collectionView atIndexPath:indexPath];
for (VipMedalSeatVo *vo in self.vipSeatVo) {
if (vo.medalSeatNum-1 == indexPath.row) {
[cell updateVIPLevel:vo.vipLevel];
break;
}
}
return cell;
} else if (collectionView == self.medalsAreaCollectionView) {
MedalsWearingListCollectionViewCell *cell = [MedalsWearingListCollectionViewCell cellFor:collectionView atIndexPath:indexPath];
[cell updateCell:[self.allMedalsVo xpSafeObjectAtIndex:indexPath.row]];
return cell;
}
return nil;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
MedalVo *vo = [self.allMedalsVo xpSafeObjectAtIndex:indexPath.row];
if (vo) {
[self.presenter updateMedalUseStatus:vo.medalId isUse:!vo.useStatus];
}
}
#pragma mark - Refresh Actions
- (void)headerRefresh {
// TODO:
self.medalsAreaPage = 1;
[self loadMedals];
}
- (void)footerRefresh {
// TODO:
self.medalsAreaPage++;
[self loadMedals];
}
#pragma mark - Lazy Load
- (UIView *)dismissArea {
if (!_dismissArea) {
_dismissArea = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KScreenWidth, kGetScaleWidth(192))];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
[_dismissArea addGestureRecognizer:tap];
}
return _dismissArea;
}
- (UIView *)contentArea {
if (!_contentArea) {
_contentArea = [[UIView alloc] initWithFrame:CGRectMake(0, kGetScaleWidth(192), KScreenWidth, KScreenHeight - kGetScaleWidth(192))];
[_contentArea setBackgroundColor:UIColorFromRGB(0x1B0043)];
[_contentArea setCornerRadius:16 corners:kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner borderWidth:0 borderColor:[UIColor clearColor]];
UILabel *titleLabel = [UILabel labelInitWithText:YMLocalizedString(@"20.20.61_text_2") font:kFontMedium(16) textColor:[UIColor whiteColor]];
[_contentArea addSubview:titleLabel];
[titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(_contentArea);
make.top.mas_equalTo(12);
make.height.mas_equalTo(22);
}];
}
return _contentArea;
}
- (UIImageView *)controlAreaBG {
if (!_controlAreaBG) {
_controlAreaBG = [[UIImageView alloc] initWithImage:kImage(@"medals_control_bg")];
}
return _controlAreaBG;
}
- (UICollectionView *)controlAreaCollectionView {
if (!_controlAreaCollectionView) {
CGFloat length = (KScreenWidth - 60 - 21 *4)/5.0;
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(length, length);
layout.minimumInteritemSpacing = 21;
layout.minimumLineSpacing = 19;
_controlAreaCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_controlAreaCollectionView.backgroundColor = [UIColor clearColor];
_controlAreaCollectionView.delegate = self;
_controlAreaCollectionView.dataSource = self;
[MedalsWearingControlCollectionViewCell registerTo:_controlAreaCollectionView];
}
return _controlAreaCollectionView;
}
- (UICollectionView *)medalsAreaCollectionView {
if (!_medalsAreaCollectionView) {
CGFloat length = kGetScaleWidth(166);
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(length, length);
layout.minimumInteritemSpacing = 12;
layout.minimumLineSpacing = 14;
_medalsAreaCollectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_medalsAreaCollectionView.backgroundColor = [UIColor clearColor];
_medalsAreaCollectionView.delegate = self;
_medalsAreaCollectionView.dataSource = self;
[MedalsWearingListCollectionViewCell registerTo:_medalsAreaCollectionView];
}
return _medalsAreaCollectionView;
}
@end