238 lines
8.0 KiB
Objective-C
238 lines
8.0 KiB
Objective-C
//
|
|
// QXGiftDisplayManager.m
|
|
// Test
|
|
//
|
|
// Created by 启星 on 2025/10/20.
|
|
//
|
|
|
|
|
|
// QXGiftDisplayManager.m
|
|
#import "QXGiftDisplayManager.h"
|
|
#import "QXGiftDisplayView.h"
|
|
|
|
@interface QXGiftDisplayManager () <QXGiftDisplayViewDelegate>
|
|
|
|
@property (nonatomic, weak) UIView *containerView;
|
|
@property (nonatomic, strong) NSMutableArray<QXGiftDisplayView *> *displayViews;
|
|
@property (nonatomic, strong) NSMutableArray<QXRoomChatListModel *> *giftQueue;
|
|
@property (nonatomic, strong) NSMutableDictionary *accumulatedGifts;
|
|
@property (nonatomic, strong) NSMutableDictionary *waitingUpdateGifts; // 等待更新的礼物
|
|
@property (nonatomic, assign) BOOL isProcessingQueue; // 防止重复处理队列
|
|
|
|
@end
|
|
|
|
@implementation QXGiftDisplayManager
|
|
|
|
+ (instancetype)sharedManager {
|
|
static QXGiftDisplayManager *instance = nil;
|
|
static dispatch_once_t onceToken;
|
|
dispatch_once(&onceToken,^{
|
|
instance = [[QXGiftDisplayManager alloc] init];
|
|
});
|
|
return instance;
|
|
}
|
|
|
|
- (instancetype)init {
|
|
self = [super init];
|
|
if (self) {
|
|
_displayViews = [NSMutableArray array];
|
|
_giftQueue = [NSMutableArray array];
|
|
_accumulatedGifts = [NSMutableDictionary dictionary];
|
|
_waitingUpdateGifts = [NSMutableDictionary dictionary];
|
|
_isProcessingQueue = NO;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)setupDisplayViewInContainer:(UIView *)container {
|
|
self.containerView = container;
|
|
[self createDisplayViews];
|
|
}
|
|
|
|
- (void)createDisplayViews {
|
|
if (self.displayViews.count > 0) return;
|
|
|
|
CGFloat viewHeight = 40;
|
|
CGFloat spacing = 10;
|
|
CGFloat topMargin = 400;
|
|
CGFloat width = 290;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
CGFloat y = topMargin + (viewHeight + spacing) * i;
|
|
CGRect frame = CGRectMake(0, y, width, viewHeight);
|
|
|
|
QXGiftDisplayView *displayView = [[QXGiftDisplayView alloc] initWithFrame:frame];
|
|
displayView.delegate = self;
|
|
displayView.tag = 1000 + i; // 设置tag便于调试
|
|
displayView.alpha = 0.0;
|
|
|
|
[self.containerView addSubview:displayView];
|
|
[self.displayViews addObject:displayView];
|
|
|
|
NSLog(@"创建飘屏视图 %d", i);
|
|
}
|
|
}
|
|
|
|
- (void)receiveGift:(QXRoomChatListModel *)gift {
|
|
if (!gift) return;
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self internalReceiveGift:gift];
|
|
});
|
|
}
|
|
|
|
- (void)internalReceiveGift:(QXRoomChatListModel *)gift {
|
|
// 查找正在显示的同类型礼物
|
|
QXGiftDisplayView *displayingView = [self findDisplayingViewForGift:gift];
|
|
|
|
if (displayingView) {
|
|
// 找到正在显示的视图,直接累加
|
|
NSString *key = [self giftKeyForGift:gift];
|
|
QXRoomChatListModel *accumulatedGift = self.accumulatedGifts[key];
|
|
if (accumulatedGift) {
|
|
NSInteger gift_num = accumulatedGift.gift_num.integerValue;
|
|
gift_num += gift.gift_num.integerValue;
|
|
accumulatedGift.gift_num = [NSString stringWithFormat:@"%ld",gift_num];
|
|
[displayingView updateGiftCount:accumulatedGift.gift_num.integerValue];
|
|
NSLog(@"礼物累加: %@ x%@", gift.GiftInfo.gift_name, accumulatedGift.gift_num);
|
|
}
|
|
} else {
|
|
// 新礼物,检查是否可以立即显示
|
|
QXGiftDisplayView *availableView = [self findAvailableDisplayView];
|
|
if (availableView) {
|
|
// 有可用视图,立即显示
|
|
NSString *key = [self giftKeyForGift:gift];
|
|
self.accumulatedGifts[key] = [gift copy];
|
|
[availableView showGift:gift];
|
|
NSLog(@"立即显示礼物在视图 %ld", (long)availableView.tag);
|
|
} else {
|
|
// 没有可用视图,加入队列
|
|
[self.giftQueue addObject:gift];
|
|
NSLog(@"加入队列,当前队列长度: %lu", (unsigned long)self.giftQueue.count);
|
|
}
|
|
}
|
|
|
|
// 处理队列
|
|
[self processGiftQueue];
|
|
}
|
|
|
|
- (QXGiftDisplayView *)findDisplayingViewForGift:(QXRoomChatListModel *)gift {
|
|
for (QXGiftDisplayView *view in self.displayViews) {
|
|
if (view.isAnimating && [view.currentGift isSameGiftFromSameSender:gift]) {
|
|
return view;
|
|
}
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
- (QXGiftDisplayView *)findAvailableDisplayView {
|
|
for (QXGiftDisplayView *view in self.displayViews) {
|
|
if (!view.isAnimating) {
|
|
return view;
|
|
}
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
- (void)processGiftQueue {
|
|
if (self.isProcessingQueue) {
|
|
return;
|
|
}
|
|
|
|
self.isProcessingQueue = YES;
|
|
|
|
// 循环处理队列直到队列为空或没有可用视图
|
|
while (self.giftQueue.count > 0) {
|
|
QXGiftDisplayView *availableView = [self findAvailableDisplayView];
|
|
if (!availableView) {
|
|
break;
|
|
}
|
|
|
|
QXRoomChatListModel *gift = self.giftQueue.firstObject;
|
|
[self.giftQueue removeObjectAtIndex:0];
|
|
|
|
// 检查是否已经有同类型礼物在显示
|
|
QXGiftDisplayView *displayingView = [self findDisplayingViewForGift:gift];
|
|
if (!displayingView) {
|
|
NSString *key = [self giftKeyForGift:gift];
|
|
self.accumulatedGifts[key] = [gift copy];
|
|
[availableView showGift:gift];
|
|
NSLog(@"从队列显示礼物: %@", gift.GiftInfo.gift_name);
|
|
} else {
|
|
// 如果已经在显示,累加到现有视图
|
|
NSString *key = [self giftKeyForGift:gift];
|
|
QXRoomChatListModel *accumulatedGift = self.accumulatedGifts[key];
|
|
if (accumulatedGift) {
|
|
NSInteger gift_num = accumulatedGift.gift_num.integerValue;
|
|
gift_num += gift.gift_num.integerValue;
|
|
accumulatedGift.gift_num = [NSString stringWithFormat:@"%ld",gift_num];
|
|
[displayingView updateGiftCount:accumulatedGift.gift_num.integerValue];
|
|
NSLog(@"队列礼物累加到现有显示: %@ x%@", gift.GiftInfo.gift_name, accumulatedGift.gift_num);
|
|
}
|
|
}
|
|
}
|
|
|
|
self.isProcessingQueue = NO;
|
|
|
|
// 打印队列状态
|
|
if (self.giftQueue.count > 0) {
|
|
NSLog(@"队列中还有 %lu 个礼物等待显示", (unsigned long)self.giftQueue.count);
|
|
}
|
|
}
|
|
|
|
- (NSString *)giftKeyForGift:(QXRoomChatListModel *)gift {
|
|
return [NSString stringWithFormat:@"%@_%@_%@", gift.FromUserInfo.nickname ?: @"unknown", gift.GiftInfo.gift_id ?: @"unknown",gift.ToUserInfo.nickname ?: @"unknown"];
|
|
}
|
|
|
|
#pragma mark - QXGiftDisplayViewDelegate
|
|
|
|
- (void)QXGiftDisplayViewDidFinishAnimation:(QXGiftDisplayView *)view {
|
|
NSLog(@"飘屏动画结束: %ld", (long)view.tag);
|
|
|
|
// 从累加记录中移除
|
|
if (view.currentGift) {
|
|
NSString *key = [self giftKeyForGift:view.currentGift];
|
|
[self.accumulatedGifts removeObjectForKey:key];
|
|
NSLog(@"移除累加记录: %@", key);
|
|
}
|
|
|
|
// 重置视图状态
|
|
view.currentGift = nil;
|
|
view.isAnimating = NO;
|
|
|
|
// 延迟一下再处理队列,确保视图状态完全重置
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
[self processGiftQueue];
|
|
});
|
|
}
|
|
|
|
- (void)clearAll {
|
|
NSLog(@"清空所有礼物和队列");
|
|
|
|
for (QXGiftDisplayView *view in self.displayViews) {
|
|
[view finishAnimationImmediately];
|
|
[view removeFromSuperview];
|
|
}
|
|
[self.displayViews removeAllObjects];
|
|
[self.giftQueue removeAllObjects];
|
|
[self.accumulatedGifts removeAllObjects];
|
|
[self.waitingUpdateGifts removeAllObjects];
|
|
|
|
self.isProcessingQueue = NO;
|
|
}
|
|
|
|
// 调试方法
|
|
- (void)printDebugInfo {
|
|
NSLog(@"=== 飘屏管理器状态 ===");
|
|
NSLog(@"队列长度: %lu", (unsigned long)self.giftQueue.count);
|
|
NSLog(@"累加记录: %lu", (unsigned long)self.accumulatedGifts.count);
|
|
|
|
for (int i = 0; i < self.displayViews.count; i++) {
|
|
QXGiftDisplayView *view = self.displayViews[i];
|
|
NSLog(@"视图 %d: 动画中=%@, 礼物=%@", i, view.isAnimating ? @"是" : @"否", view.currentGift.GiftInfo.gift_name ?: @"无");
|
|
}
|
|
NSLog(@"====================");
|
|
}
|
|
|
|
@end
|