From a0fc15fefd4946feec081e9fca325ca2ccba5ce6 Mon Sep 17 00:00:00 2001 From: edwinQQQ Date: Wed, 18 Jun 2025 19:47:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20MedalsCollectionViewCell?= =?UTF-8?q?=20=E5=92=8C=20MedalsDetailView=20=E4=BB=A5=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=B8=A6=E5=9B=BE=E7=89=87=E7=9A=84=E7=AD=89=E7=BA=A7=E6=8C=87?= =?UTF-8?q?=E7=A4=BA=E5=99=A8=EF=BC=8C=E6=96=B0=E5=A2=9E=20MedalsLevelIndi?= =?UTF-8?q?catorType=20=E6=9E=9A=E4=B8=BE=E4=BB=A5=E5=8C=BA=E5=88=86?= =?UTF-8?q?=E6=8C=87=E7=A4=BA=E5=99=A8=E7=B1=BB=E5=9E=8B=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=89=8B=E5=8A=BF=E8=AF=86=E5=88=AB=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E4=BF=9D=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C?= =?UTF-8?q?=E6=B5=81=E7=95=85=EF=BC=8C=E4=BF=9D=E6=8C=81=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E4=B8=80=E8=87=B4=E6=80=A7=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/Medals/MedalsCollectionViewCell.m | 11 ++ .../YMMine/View/Medals/MedalsDetailView.m | 47 ++++---- .../View/Medals/MedalsLevelIndicatorView.h | 13 +++ .../View/Medals/MedalsLevelIndicatorView.m | 107 ++++++++++++++++++ 4 files changed, 153 insertions(+), 25 deletions(-) diff --git a/YuMi/Modules/YMMine/View/Medals/MedalsCollectionViewCell.m b/YuMi/Modules/YMMine/View/Medals/MedalsCollectionViewCell.m index 9de94ebc..ba7c65d9 100644 --- a/YuMi/Modules/YMMine/View/Medals/MedalsCollectionViewCell.m +++ b/YuMi/Modules/YMMine/View/Medals/MedalsCollectionViewCell.m @@ -169,6 +169,17 @@ [self.levelIndicatorView setupWithMaxLevel:itemVos.medalLevel]; [self.levelIndicatorView setSelectedLevel:1 animated:NO]; + // 设置指示器类型为带图片 + self.levelIndicatorView.indicatorType = MedalsLevelIndicatorTypeNormal; + + // 为每个等级设置对应的图片 + for (NSInteger i = 0; i < itemVos.medalVos.count; i++) { + MedalVos *medalVo = [itemVos.medalVos xpSafeObjectAtIndex:i]; + if (medalVo) { + [self.levelIndicatorView setImageUrl:medalVo.picUrl forLevel:i + 1]; + } + } + [self updateDisplayWithCurrentModel]; } diff --git a/YuMi/Modules/YMMine/View/Medals/MedalsDetailView.m b/YuMi/Modules/YMMine/View/Medals/MedalsDetailView.m index 09b7e680..b1af74ff 100644 --- a/YuMi/Modules/YMMine/View/Medals/MedalsDetailView.m +++ b/YuMi/Modules/YMMine/View/Medals/MedalsDetailView.m @@ -104,27 +104,18 @@ } }; - // 添加点击手势识别器,用于点击背景空白处移除视图 - UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleBackgroundTap:)]; - [self addGestureRecognizer:tapGesture]; - - // 为内容区域添加手势识别器,防止点击内容区域时关闭视图 - UIView *contentArea = [[UIView alloc] init]; - contentArea.backgroundColor = [UIColor clearColor]; - [self addSubview:contentArea]; - [contentArea mas_makeConstraints:^(MASConstraintMaker *make) { - make.center.mas_equalTo(self); - make.width.mas_equalTo(280); - make.top.mas_equalTo(self.imageView).offset(-20); - // make.bottom.mas_equalTo(self.levelIndicatorView).offset(20); - make.height.mas_equalTo(360); + // 在 levelIndicatorView 底部添加一个视图作为关闭按钮区域 + UIView *closeButtonView = [[UIView alloc] init]; + closeButtonView.backgroundColor = [UIColor clearColor]; + [self addSubview:closeButtonView]; + [closeButtonView mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.mas_equalTo(self.levelIndicatorView.mas_bottom).offset(20); + make.bottom.leading.trailing.mas_equalTo(self); }]; - UITapGestureRecognizer *contentTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleContentTap:)]; - [contentArea addGestureRecognizer:contentTapGesture]; - - // 设置手势优先级,确保内容区域的手势优先处理 - [tapGesture requireGestureRecognizerToFail:contentTapGesture]; + // 添加点击手势到关闭按钮区域 + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleBackgroundTap:)]; + [closeButtonView addGestureRecognizer:tapGesture]; } - (void)setDetailItemVo:(MedalSeriesVo *)detailItemVo { @@ -135,6 +126,17 @@ [self.levelIndicatorView setupWithMaxLevel:self.currentSeriesItemVO.medalLevel]; [self.levelIndicatorView setSelectedLevel:1 animated:NO]; + // 设置指示器类型为带图片 + self.levelIndicatorView.indicatorType = MedalsLevelIndicatorTypeWithImage; + + // 为每个等级设置对应的图片 + for (NSInteger i = 0; i < self.currentSeriesItemVO.medalVos.count; i++) { + MedalVos *medalVo = [self.currentSeriesItemVO.medalVos xpSafeObjectAtIndex:i]; + if (medalVo) { + [self.levelIndicatorView setImageUrl:medalVo.picUrl forLevel:i + 1]; + } + } + [self updateDisplayWithCurrentModel]; } @@ -238,16 +240,11 @@ return _mp4View; } -// 添加处理背景点击的方法 +// 修改处理背景点击的方法名称,使其更符合实际功能 - (void)handleBackgroundTap:(UITapGestureRecognizer *)gesture { [self removeFromSuperview]; } -// 添加处理内容区域点击的方法(仅用于阻止背景点击事件) -- (void)handleContentTap:(UITapGestureRecognizer *)gesture { - // 什么都不做,只是阻止事件传递 -} - // 重写 removeFromSuperview 方法,确保在移除前停止 MP4 播放 - (void)removeFromSuperview { // 停止 MP4 播放并释放资源 diff --git a/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.h b/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.h index 5a05d9e8..22a679fc 100644 --- a/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.h +++ b/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.h @@ -9,13 +9,26 @@ NS_ASSUME_NONNULL_BEGIN +typedef NS_ENUM(NSInteger, MedalsLevelIndicatorType) { + MedalsLevelIndicatorTypeNormal = 0, // 普通类型(只有圆点和文字) + MedalsLevelIndicatorTypeWithImage = 1, // 带图片类型(圆点上方有图片) +}; + @interface MedalsLevelIndicatorView : UIView @property (nonatomic, copy) void (^levelSelectedBlock)(NSInteger level); +@property (nonatomic, assign) MedalsLevelIndicatorType indicatorType; - (void)setupWithMaxLevel:(NSInteger)maxLevel; - (void)setSelectedLevel:(NSInteger)level animated:(BOOL)animated; +/** + * 设置指定等级的图片 + * @param imageUrl 图片URL + * @param level 等级 + */ +- (void)setImageUrl:(NSString *)imageUrl forLevel:(NSInteger)level; + @end NS_ASSUME_NONNULL_END diff --git a/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.m b/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.m index 123028a5..e34c450e 100644 --- a/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.m +++ b/YuMi/Modules/YMMine/View/Medals/MedalsLevelIndicatorView.m @@ -6,17 +6,23 @@ // #import "MedalsLevelIndicatorView.h" +#import "UIImage+Utils.h" // 等级指示器视图 @interface LevelItemView : UIView @property (nonatomic, strong) UILabel *levelLabel; @property (nonatomic, strong) UIView *dotView; // 圆点视图 +@property (nonatomic, strong) NetImageView *imageView; // 图片视图 @property (nonatomic, assign) BOOL isSelected; @property (nonatomic, assign) NSInteger level; +@property (nonatomic, assign) BOOL hasImage; +@property (nonatomic, strong) UIImage *originalImage; // 保存原始彩色图片 +@property (nonatomic, strong) UIImage *grayImage; // 保存灰度图片 - (instancetype)initWithLevel:(NSInteger)level; - (void)setSelected:(BOOL)selected animated:(BOOL)animated; +- (void)setImageUrl:(NSString *)imageUrl; @end @@ -27,6 +33,7 @@ if (self) { _level = level; _isSelected = NO; + _hasImage = NO; // 创建圆点视图 _dotView = [[UIView alloc] init]; @@ -58,6 +65,65 @@ return self; } +- (void)setImageUrl:(NSString *)imageUrl { + if (!_imageView) { + // 创建图片视图 + _imageView = [[NetImageView alloc] init]; + _imageView.contentMode = UIViewContentModeScaleAspectFill; + _imageView.layer.cornerRadius = 15; + _imageView.clipsToBounds = YES; + [self addSubview:_imageView]; + + [_imageView mas_makeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self); + make.bottom.mas_equalTo(_dotView.mas_top).offset(-4); + make.width.height.mas_equalTo(30); + }]; + + // 调整圆点位置 + [_dotView mas_remakeConstraints:^(MASConstraintMaker *make) { + make.centerX.mas_equalTo(self); + make.top.mas_equalTo(_imageView.mas_bottom).offset(4); + make.width.height.mas_equalTo(6); + }]; + } + + _hasImage = YES; + + // 调试时使用测试URL + #ifdef DEBUG + NSString *testUrl = @"https://img.toto.im/mw600/66b3de17ly1i2jopju47bj20xc1e0dx4.jpg.webp"; + imageUrl = testUrl; + NSLog(@"调试模式: 使用测试图片URL: %@", testUrl); + #endif + + // 加载图片并处理灰度效果 + @kWeakify(self); + [_imageView loadImageWithUrl:imageUrl completion:^(UIImage * _Nullable image, NSURL * _Nonnull url) { + @kStrongify(self); + if (image) { + self.originalImage = image; + self.grayImage = [image grayscaleImage]; + [self updateImageEffect]; + } + }]; +} + +// 更新图片效果 +- (void)updateImageEffect { + if (!_hasImage || !_imageView) { + return; + } + + if (_isSelected && _originalImage) { + // 选中状态:显示彩色图片 + _imageView.image = _originalImage; + } else if (!_isSelected && _grayImage) { + // 非选中状态:显示灰度图片 + _imageView.image = _grayImage; + } +} + - (void)setSelected:(BOOL)selected animated:(BOOL)animated { if (_isSelected == selected) { return; @@ -69,6 +135,11 @@ UIColor *color = selected ? [UIColor whiteColor] : UIColorFromRGB(0x8B54E8); self.levelLabel.textColor = color; self.dotView.backgroundColor = color; + + // 如果有图片,更新图片效果 + if (self.hasImage) { + [self updateImageEffect]; + } }; if (animated) { @@ -98,6 +169,7 @@ _levelItems = [NSMutableArray array]; _connectionLines = [NSMutableArray array]; _selectedLevel = 1; + _indicatorType = MedalsLevelIndicatorTypeNormal; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; [self addGestureRecognizer:tapGesture]; @@ -166,6 +238,9 @@ // 默认选中LV1 [self setSelectedLevel:1 animated:NO]; + + // 根据类型设置图片可见性 + [self updateImageVisibility]; } - (void)layoutSubviews { @@ -220,6 +295,38 @@ } } +- (void)setIndicatorType:(MedalsLevelIndicatorType)indicatorType { + _indicatorType = indicatorType; + + // 如果已经创建了视图,需要根据类型进行调整 + if (_levelItems.count > 0) { + [self updateImageVisibility]; + } +} + +// 根据指示器类型更新图片可见性 +- (void)updateImageVisibility { + for (LevelItemView *item in _levelItems) { + if (item.imageView) { + item.imageView.hidden = (_indicatorType == MedalsLevelIndicatorTypeNormal); + } + } +} + +- (void)setImageUrl:(NSString *)imageUrl forLevel:(NSInteger)level { + if (level < 1 || level > _maxLevel || level > _levelItems.count) { + return; + } + + LevelItemView *item = _levelItems[level - 1]; + [item setImageUrl:imageUrl]; + + // 根据当前类型设置图片可见性 + if (item.imageView) { + item.imageView.hidden = (_indicatorType == MedalsLevelIndicatorTypeNormal); + } +} + - (void)handleTap:(UITapGestureRecognizer *)gesture { CGPoint location = [gesture locationInView:self];