新增等级指示器视图和容器视图,更新 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",
|
"Nonnull",
|
||||||
"NSEC",
|
"NSEC",
|
||||||
"Procotol",
|
"Procotol",
|
||||||
|
"QGVAP",
|
||||||
"Subview",
|
"Subview",
|
||||||
"Superview",
|
"Superview",
|
||||||
"Uids"
|
"Uids"
|
||||||
|
@@ -10,6 +10,241 @@
|
|||||||
#import <QGVAPWrapView.h>
|
#import <QGVAPWrapView.h>
|
||||||
#import "XPRoomGiftAnimationParser.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 ()
|
@interface MedalsCollectionViewCell ()
|
||||||
|
|
||||||
@property(nonatomic, copy) NSString *imagePath;
|
@property(nonatomic, copy) NSString *imagePath;
|
||||||
@@ -20,8 +255,10 @@
|
|||||||
@property(nonatomic, strong) XPRoomGiftAnimationParser *mp4Parser;
|
@property(nonatomic, strong) XPRoomGiftAnimationParser *mp4Parser;
|
||||||
@property (nonatomic, strong) UILabel *titleLabel;
|
@property (nonatomic, strong) UILabel *titleLabel;
|
||||||
@property (nonatomic, strong) UILabel *subLabel;
|
@property (nonatomic, strong) UILabel *subLabel;
|
||||||
|
@property (nonatomic, strong) LevelIndicatorView *levelIndicatorView;
|
||||||
|
|
||||||
@property (nonatomic, strong) MedalVos *displayModel;
|
@property (nonatomic, strong) MedalVos *displayModel;
|
||||||
|
@property (nonatomic, strong) MedalSeriesItemVo *currentItemVo;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MedalsCollectionViewCell
|
@implementation MedalsCollectionViewCell
|
||||||
@@ -82,15 +319,50 @@
|
|||||||
[self.subLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.subLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.centerX.mas_equalTo(self.contentView);
|
make.centerX.mas_equalTo(self.contentView);
|
||||||
make.top.mas_equalTo(self.titleLabel.mas_bottom).offset(7);
|
make.top.mas_equalTo(self.titleLabel.mas_bottom).offset(7);
|
||||||
make.leading.trailing.mas_equalTo(self.contentView).inset( 3);
|
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;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateCell:(MedalSeriesVo *)model {
|
- (void)updateCell:(MedalSeriesVo *)model {
|
||||||
MedalSeriesItemVo *itemVos = [model.medalSeries xpSafeObjectAtIndex:0];
|
MedalSeriesItemVo *itemVos = [model.medalSeries xpSafeObjectAtIndex:0];
|
||||||
|
self.currentItemVo = itemVos;
|
||||||
self.displayModel = [itemVos.medalVos xpSafeObjectAtIndex:0];
|
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) {
|
||||||
if ([self.displayModel.picUrl hasSuffix:@"mp4"]) {
|
if ([self.displayModel.picUrl hasSuffix:@"mp4"]) {
|
||||||
[self setMp4Path:self.displayModel.picUrl];
|
[self setMp4Path:self.displayModel.picUrl];
|
||||||
@@ -109,7 +381,6 @@
|
|||||||
[NSDate timestampSwitchTime:self.displayModel.expireSeconds
|
[NSDate timestampSwitchTime:self.displayModel.expireSeconds
|
||||||
formatter:@"yyyy/mm/dd"]];
|
formatter:@"yyyy/mm/dd"]];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user