// // QXGiftDisplayManager.m // Test // // Created by 启星 on 2025/10/20. // // QXGiftDisplayManager.m #import "QXGiftDisplayManager.h" #import "QXGiftDisplayView.h" @interface QXGiftDisplayManager () @property (nonatomic, weak) UIView *containerView; @property (nonatomic, strong) NSMutableArray *displayViews; @property (nonatomic, strong) NSMutableArray *giftQueue; @property (nonatomic, strong) NSMutableDictionary *accumulatedGifts; @property (nonatomic, strong) NSMutableDictionary *waitingUpdateGifts; // 等待更新的礼物 @property (nonatomic, assign) BOOL isProcessingQueue; // 防止重复处理队列 @property (nonatomic, assign) BOOL isInBackground; // 防止重复处理队列 @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 = 460; 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 (self.isInBackground) { return; } 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)inBackGround{ self.isInBackground = YES; for (QXGiftDisplayView *view in self.displayViews) { [view finishAnimationImmediately]; } [self.giftQueue removeAllObjects]; [self.accumulatedGifts removeAllObjects]; [self.waitingUpdateGifts removeAllObjects]; self.isProcessingQueue = NO; } -(void)becomeFront{ self.isInBackground = 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