新增等级指示器视图和容器视图,更新 MedalsCollectionViewCell 以集成等级指示器功能,支持等级选择回调。更新 .vscode/settings.json 文件以包含新组件 QGVAP 的配置,保持代码结构一致性。
This commit is contained in:
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -16,6 +16,7 @@
|
||||
"Nonnull",
|
||||
"NSEC",
|
||||
"Procotol",
|
||||
"QGVAP",
|
||||
"Subview",
|
||||
"Superview",
|
||||
"Uids"
|
||||
|
@@ -10,6 +10,241 @@
|
||||
#import <QGVAPWrapView.h>
|
||||
#import "XPRoomGiftAnimationParser.h"
|
||||
|
||||
// 等级指示器视图
|
||||
@interface LevelItemView : UIView
|
||||
|
||||
@property (nonatomic, strong) UILabel *levelLabel;
|
||||
@property (nonatomic, strong) UIView *dotView; // 圆点视图
|
||||
@property (nonatomic, assign) BOOL isSelected;
|
||||
@property (nonatomic, assign) NSInteger level;
|
||||
|
||||
- (instancetype)initWithLevel:(NSInteger)level;
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LevelItemView
|
||||
|
||||
- (instancetype)initWithLevel:(NSInteger)level {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_level = level;
|
||||
_isSelected = NO;
|
||||
|
||||
// 创建圆点视图
|
||||
_dotView = [[UIView alloc] init];
|
||||
_dotView.backgroundColor = UIColorFromRGB(0x8B54E8);
|
||||
_dotView.layer.cornerRadius = 3; // 圆点半径
|
||||
_dotView.clipsToBounds = YES;
|
||||
[self addSubview:_dotView];
|
||||
|
||||
// 创建等级标签
|
||||
self.levelLabel = [UILabel labelInitWithText:[NSString stringWithFormat:@"LV%ld", (long)level]
|
||||
font:kFontMedium(10)
|
||||
textColor:UIColorFromRGB(0x8B54E8)];
|
||||
self.levelLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:self.levelLabel];
|
||||
|
||||
// 布局
|
||||
[_dotView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.top.mas_equalTo(self);
|
||||
make.width.height.mas_equalTo(6); // 圆点大小
|
||||
}];
|
||||
|
||||
[self.levelLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self);
|
||||
make.top.mas_equalTo(_dotView.mas_bottom).offset(4); // 圆点和文字的间距
|
||||
make.leading.trailing.bottom.mas_equalTo(self);
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
|
||||
if (_isSelected == selected) {
|
||||
return;
|
||||
}
|
||||
|
||||
_isSelected = selected;
|
||||
|
||||
void (^updateBlock)(void) = ^{
|
||||
UIColor *color = selected ? [UIColor whiteColor] : UIColorFromRGB(0x8B54E8);
|
||||
self.levelLabel.textColor = color;
|
||||
self.dotView.backgroundColor = color;
|
||||
};
|
||||
|
||||
if (animated) {
|
||||
[UIView animateWithDuration:0.2 animations:updateBlock];
|
||||
} else {
|
||||
updateBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// 等级指示器容器视图
|
||||
@interface LevelIndicatorView : UIView
|
||||
|
||||
@property (nonatomic, strong) NSMutableArray<LevelItemView *> *levelItems;
|
||||
@property (nonatomic, strong) NSMutableArray<UIView *> *connectionLines; // 连接线数组
|
||||
@property (nonatomic, assign) NSInteger maxLevel;
|
||||
@property (nonatomic, assign) NSInteger selectedLevel;
|
||||
@property (nonatomic, copy) void (^levelSelectedBlock)(NSInteger level);
|
||||
|
||||
@end
|
||||
|
||||
@implementation LevelIndicatorView
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_levelItems = [NSMutableArray array];
|
||||
_connectionLines = [NSMutableArray array];
|
||||
_selectedLevel = 1;
|
||||
|
||||
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
|
||||
[self addGestureRecognizer:tapGesture];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setupWithMaxLevel:(NSInteger)maxLevel {
|
||||
if (maxLevel < 0) {
|
||||
maxLevel = 1;
|
||||
}
|
||||
if (_maxLevel == maxLevel && _levelItems.count == maxLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
_maxLevel = maxLevel;
|
||||
|
||||
// 清除现有的等级指示器和连接线
|
||||
for (UIView *view in _levelItems) {
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
[_levelItems removeAllObjects];
|
||||
|
||||
for (UIView *line in _connectionLines) {
|
||||
[line removeFromSuperview];
|
||||
}
|
||||
[_connectionLines removeAllObjects];
|
||||
|
||||
// 创建新的等级指示器
|
||||
CGFloat itemWidth = 25.0; // 每个等级指示器的宽度
|
||||
CGFloat spacing = 15.0; // 等级指示器之间的间距
|
||||
CGFloat totalWidth = itemWidth * maxLevel + spacing * (maxLevel - 1);
|
||||
CGFloat startX = (self.bounds.size.width - totalWidth) / 2;
|
||||
|
||||
for (NSInteger i = 1; i <= maxLevel; i++) {
|
||||
// 创建等级指示器
|
||||
LevelItemView *levelItem = [[LevelItemView alloc] initWithLevel:i];
|
||||
[self addSubview:levelItem];
|
||||
[_levelItems addObject:levelItem];
|
||||
|
||||
// 设置位置
|
||||
CGFloat x = startX + (i - 1) * (itemWidth + spacing);
|
||||
[levelItem mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.mas_equalTo(itemWidth);
|
||||
make.height.mas_equalTo(self);
|
||||
make.centerY.mas_equalTo(self);
|
||||
make.leading.mas_equalTo(self).offset(x);
|
||||
}];
|
||||
|
||||
// 如果不是第一个,添加连接线
|
||||
if (i > 1) {
|
||||
UIView *line = [[UIView alloc] init];
|
||||
line.backgroundColor = UIColorFromRGB(0x8B54E8); // 默认非选中颜色
|
||||
[self insertSubview:line atIndex:0];
|
||||
[_connectionLines addObject:line];
|
||||
|
||||
// 连接线位置:从上一个圆点到当前圆点
|
||||
[line mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.mas_equalTo(1); // 线的高度
|
||||
make.centerY.mas_equalTo(levelItem.dotView);
|
||||
make.leading.mas_equalTo(_levelItems[i-2].dotView.mas_centerX);
|
||||
make.trailing.mas_equalTo(levelItem.dotView.mas_centerX);
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
// 默认选中LV1
|
||||
[self setSelectedLevel:1 animated:NO];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
|
||||
if (_maxLevel > 0 && _levelItems.count > 0) {
|
||||
// 重新计算布局,确保居中显示
|
||||
CGFloat itemWidth = 25.0;
|
||||
CGFloat spacing = 15.0;
|
||||
CGFloat totalWidth = itemWidth * _maxLevel + spacing * (_maxLevel - 1);
|
||||
CGFloat startX = (self.bounds.size.width - totalWidth) / 2;
|
||||
|
||||
for (NSInteger i = 0; i < _levelItems.count; i++) {
|
||||
LevelItemView *item = _levelItems[i];
|
||||
CGFloat x = startX + i * (itemWidth + spacing);
|
||||
[item mas_updateConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(self).offset(x);
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setSelectedLevel:(NSInteger)level animated:(BOOL)animated {
|
||||
if (level < 1 || level > _maxLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
_selectedLevel = level;
|
||||
|
||||
// 更新等级指示器状态
|
||||
for (NSInteger i = 0; i < _levelItems.count; i++) {
|
||||
LevelItemView *item = _levelItems[i];
|
||||
[item setSelected:(i + 1) <= level animated:animated];
|
||||
}
|
||||
|
||||
// 更新连接线状态
|
||||
for (NSInteger i = 0; i < _connectionLines.count; i++) {
|
||||
UIView *line = _connectionLines[i];
|
||||
// 连接线的状态取决于它连接的两个等级指示器是否都被选中
|
||||
// 如果连接线两端的等级指示器都被选中,则连接线也被选中
|
||||
BOOL isSelected = (i + 2) <= level;
|
||||
|
||||
void (^updateBlock)(void) = ^{
|
||||
line.backgroundColor = isSelected ? [UIColor whiteColor] : UIColorFromRGB(0x8B54E8);
|
||||
};
|
||||
|
||||
if (animated) {
|
||||
[UIView animateWithDuration:0.2 animations:updateBlock];
|
||||
} else {
|
||||
updateBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleTap:(UITapGestureRecognizer *)gesture {
|
||||
CGPoint location = [gesture locationInView:self];
|
||||
|
||||
for (NSInteger i = 0; i < _levelItems.count; i++) {
|
||||
LevelItemView *item = _levelItems[i];
|
||||
CGPoint itemLocation = [self convertPoint:location toView:item];
|
||||
|
||||
if (CGRectContainsPoint(item.bounds, itemLocation)) {
|
||||
NSInteger level = i + 1;
|
||||
[self setSelectedLevel:level animated:YES];
|
||||
|
||||
if (_levelSelectedBlock) {
|
||||
_levelSelectedBlock(level);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface MedalsCollectionViewCell ()
|
||||
|
||||
@property(nonatomic, copy) NSString *imagePath;
|
||||
@@ -20,8 +255,10 @@
|
||||
@property(nonatomic, strong) XPRoomGiftAnimationParser *mp4Parser;
|
||||
@property (nonatomic, strong) UILabel *titleLabel;
|
||||
@property (nonatomic, strong) UILabel *subLabel;
|
||||
@property (nonatomic, strong) LevelIndicatorView *levelIndicatorView;
|
||||
|
||||
@property (nonatomic, strong) MedalVos *displayModel;
|
||||
@property (nonatomic, strong) MedalSeriesItemVo *currentItemVo;
|
||||
@end
|
||||
|
||||
@implementation MedalsCollectionViewCell
|
||||
@@ -84,13 +321,48 @@
|
||||
make.top.mas_equalTo(self.titleLabel.mas_bottom).offset(7);
|
||||
make.leading.trailing.mas_equalTo(self.contentView).inset(3);
|
||||
}];
|
||||
|
||||
// 添加等级指示器
|
||||
self.levelIndicatorView = [[LevelIndicatorView alloc] init];
|
||||
[self.contentView addSubview:self.levelIndicatorView];
|
||||
[self.levelIndicatorView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self.contentView);
|
||||
make.bottom.mas_equalTo(self.contentView).offset(-8);
|
||||
make.left.right.mas_greaterThanOrEqualTo(self.contentView).inset(8);
|
||||
make.height.mas_equalTo(26); // 增加高度以适应圆点和文本
|
||||
}];
|
||||
|
||||
// 设置等级选择回调
|
||||
@kWeakify(self);
|
||||
self.levelIndicatorView.levelSelectedBlock = ^(NSInteger level) {
|
||||
@kStrongify(self);
|
||||
// 处理等级选择事件
|
||||
if (self.currentItemVo && level <= self.currentItemVo.medalVos.count) {
|
||||
MedalVos *selectedMedalVo = [self.currentItemVo.medalVos xpSafeObjectAtIndex:level - 1];
|
||||
if (selectedMedalVo) {
|
||||
self.displayModel = selectedMedalVo;
|
||||
[self updateDisplayWithCurrentModel];
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateCell:(MedalSeriesVo *)model {
|
||||
MedalSeriesItemVo *itemVos = [model.medalSeries xpSafeObjectAtIndex:0];
|
||||
self.currentItemVo = itemVos;
|
||||
self.displayModel = [itemVos.medalVos xpSafeObjectAtIndex:0];
|
||||
|
||||
// 配置等级指示器
|
||||
[self.levelIndicatorView setupWithMaxLevel:itemVos.medalLevel];
|
||||
|
||||
[self.levelIndicatorView setSelectedLevel:1 animated:NO];
|
||||
|
||||
[self updateDisplayWithCurrentModel];
|
||||
}
|
||||
|
||||
- (void)updateDisplayWithCurrentModel {
|
||||
if (self.displayModel) {
|
||||
if ([self.displayModel.picUrl hasSuffix:@"mp4"]) {
|
||||
[self setMp4Path:self.displayModel.picUrl];
|
||||
@@ -109,7 +381,6 @@
|
||||
[NSDate timestampSwitchTime:self.displayModel.expireSeconds
|
||||
formatter:@"yyyy/mm/dd"]];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user