From eee967c2e1ffa846bb12947bc2d2220be1e93315 Mon Sep 17 00:00:00 2001 From: edwinQQQ Date: Wed, 27 Aug 2025 16:35:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20emoji=20=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=B8=85=E7=90=86=E5=8A=9F=E8=83=BD=E4=BB=A5=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E6=96=B0=E7=9A=84=E5=B0=BA=E5=AF=B8=E8=AE=BE=E7=BD=AE=E7=94=9F?= =?UTF-8?q?=E6=95=88=EF=BC=8C=E4=BC=98=E5=8C=96=E8=A1=A8=E6=83=85=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81=E5=B8=A6?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E5=8F=82=E6=95=B0=E7=9A=84=E8=A1=A8=E6=83=85?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E3=80=82=E5=90=8C=E6=97=B6=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95=E4=BB=A5=E9=80=82?= =?UTF-8?q?=E5=BA=94=E6=96=B0=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BD=93=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- YuMi/Appdelegate/AppDelegate+ThirdConfig.m | 3 ++ .../InputView/InputView/QEmotionHelper.h | 10 +++++ .../InputView/InputView/QEmotionHelper.m | 42 +++++++++++++++---- .../View/Session/Content/MessageContentText.m | 2 +- .../SesssionModel/MessageHeadlinesTextModel.m | 2 +- .../Content/SesssionModel/MessageTextModel.m | 2 +- .../YMRoom/Features/Boom/RoomBoomManager.m | 3 +- .../YMTabbar/View/TabbarViewController.m | 14 +++++-- .../MVP/Presenter/BaseMvpPresenter.m | 8 +++- 9 files changed, 67 insertions(+), 19 deletions(-) diff --git a/YuMi/Appdelegate/AppDelegate+ThirdConfig.m b/YuMi/Appdelegate/AppDelegate+ThirdConfig.m index 05b8755f..fb6d65d6 100644 --- a/YuMi/Appdelegate/AppDelegate+ThirdConfig.m +++ b/YuMi/Appdelegate/AppDelegate+ThirdConfig.m @@ -180,6 +180,9 @@ UIKIT_EXTERN NSString * adImageName; QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper]; faceManager.emotionArray = array; + // 清理 emoji 缓存,确保新的尺寸设置生效 + [QEmotionHelper clearEmojiCache]; + #if DEBUG // 测试图片加载 NSLog(@"表情数组加载完成,总数: %lu", (unsigned long)array.count); diff --git a/YuMi/CustomUI/InputView/InputView/QEmotionHelper.h b/YuMi/CustomUI/InputView/InputView/QEmotionHelper.h index 5d1ca39d..4ce4adf0 100644 --- a/YuMi/CustomUI/InputView/InputView/QEmotionHelper.h +++ b/YuMi/CustomUI/InputView/InputView/QEmotionHelper.h @@ -25,7 +25,17 @@ //把 @"[微笑]" 转为 @"😊" - (NSAttributedString *)obtainAttributedStringByImageKey:(NSString *)imageKey font:(UIFont *)font useCache:(BOOL)useCache; +//imageKey:[微笑] font:label的Font,返回😊 (带场景参数) +//把 @"[微笑]" 转为 @"😊" +- (NSAttributedString *)obtainAttributedStringByImageKey:(NSString *)imageKey font:(UIFont *)font useCache:(BOOL)useCache forMessageBubble:(BOOL)isMessageBubble; + //把 @"害~你好啊[微笑]" 转为 @"害~你好啊😊" - (NSMutableAttributedString *)attributedStringByText:(NSString *)text font:(UIFont *)font; +//把 @"害~你好啊[微笑]" 转为 @"害~你好啊😊" (带场景参数) +- (NSMutableAttributedString *)attributedStringByText:(NSString *)text font:(UIFont *)font forMessageBubble:(BOOL)isMessageBubble; + +// 清理 emoji 缓存,用于尺寸变更后刷新 ++ (void)clearEmojiCache; + @end diff --git a/YuMi/CustomUI/InputView/InputView/QEmotionHelper.m b/YuMi/CustomUI/InputView/InputView/QEmotionHelper.m index e4a16ad6..d2bf2b3c 100644 --- a/YuMi/CustomUI/InputView/InputView/QEmotionHelper.m +++ b/YuMi/CustomUI/InputView/InputView/QEmotionHelper.m @@ -46,6 +46,12 @@ return _sharedFaceManager; } +// 清理 emoji 缓存,用于尺寸变更后刷新 ++ (void)clearEmojiCache { + QEmotionHelper *helper = [QEmotionHelper sharedEmotionHelper]; + [helper.cacheAttributedDictionary removeAllObjects]; +} + #pragma mark - public //本方法我这里只是demo演示;实际开发中,可以改为你自己的获取表情列表的写法 //由于emotionArray包含Image,测试结果是占用0.5MB的内存(永驻) @@ -78,6 +84,11 @@ //把整段String:@"害~你好[微笑]", 转为 @"害~你好😊" - (NSMutableAttributedString *)attributedStringByText:(NSString *)text font:(UIFont *)font { + return [self attributedStringByText:text font:font forMessageBubble:NO]; +} + +//把整段String:@"害~你好[微笑]", 转为 @"害~你好😊" (带场景参数) +- (NSMutableAttributedString *)attributedStringByText:(NSString *)text font:(UIFont *)font forMessageBubble:(BOOL)isMessageBubble { if(text.length == 0){ return [[NSMutableAttributedString alloc] initWithString:@""];; } @@ -98,7 +109,7 @@ //ios15他采用了NSTextAttachmentViewProvider,具体我没研究 useCache = NO; } - NSAttributedString *imageAttributedString = [self obtainAttributedStringByImageKey:emojiKey font:font useCache:useCache]; + NSAttributedString *imageAttributedString = [self obtainAttributedStringByImageKey:emojiKey font:font useCache:useCache forMessageBubble:isMessageBubble]; if (imageAttributedString) { [intactAttributeString replaceCharactersInRange:result.range withAttributedString:imageAttributedString]; } @@ -115,6 +126,13 @@ //imageKey:[微笑] ,font:label的Font,返回😊 //把 @@"[微笑]", 转为 @"😊" - (NSAttributedString *)obtainAttributedStringByImageKey:(NSString *)imageKey font:(UIFont *)font useCache:(BOOL)useCache { + return [self obtainAttributedStringByImageKey:imageKey font:font useCache:useCache forMessageBubble:NO]; +} + +//把只是单纯的一个表情转为AttributedString (带场景参数) +//imageKey:[微笑] ,font:label的Font,返回😊 +//把 @@"[微笑]", 转为 @"😊" +- (NSAttributedString *)obtainAttributedStringByImageKey:(NSString *)imageKey font:(UIFont *)font useCache:(BOOL)useCache forMessageBubble:(BOOL)isMessageBubble { if([self.emojiHantList containsObject:imageKey]){ NSString *getImageKey = [self.emojiHansList xpSafeObjectAtIndex:[self.emojiHantList indexOfObject:imageKey]]; if(getImageKey != nil){ @@ -133,14 +151,17 @@ imageView.contentMode = UIViewContentModeScaleAspectFit; imageView.displayText = imageKey; imageView.image = image; + + // 计算 emoji 尺寸:根据场景决定是否放大 + CGFloat emojiSize = isMessageBubble ? font.lineHeight * 2.0 : font.lineHeight; // 消息气泡放大一倍 if (image) { CGFloat scale = image.size.width / image.size.height; - imageView.bounds = CGRectMake(0, 0, 20 * scale, 20); + imageView.bounds = CGRectMake(0, 0, emojiSize * scale, emojiSize); } else { - imageView.bounds = CGRectMake(0, 0, 20, 20); + imageView.bounds = CGRectMake(0, 0, emojiSize, emojiSize); } - imageView.bounds = CGRectMake(0, 0, font.lineHeight, font.lineHeight); - NSMutableAttributedString * attrString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; + + NSMutableAttributedString * attrString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height) alignToFont:font alignment:YYTextVerticalAlignmentCenter]; return attrString; } @@ -165,14 +186,17 @@ imageView.contentMode = UIViewContentModeScaleAspectFit; imageView.displayText = imageKey; imageView.image = image; + + // 计算 emoji 尺寸:根据场景决定是否放大 + CGFloat emojiSize = isMessageBubble ? font.lineHeight * 2.0 : font.lineHeight; // 消息气泡放大一倍 if (image) { CGFloat scale = image.size.width / image.size.height; - imageView.bounds = CGRectMake(0, 0, 20 * scale, 20); + imageView.bounds = CGRectMake(0, 0, emojiSize * scale, emojiSize); } else { - imageView.bounds = CGRectMake(0, 0, 20, 20); + imageView.bounds = CGRectMake(0, 0, emojiSize, emojiSize); } - imageView.bounds = CGRectMake(0, 0, font.lineHeight, font.lineHeight); - NSMutableAttributedString * attrString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height) alignToFont:[UIFont systemFontOfSize:15.0] alignment:YYTextVerticalAlignmentCenter]; + + NSMutableAttributedString * attrString = [NSMutableAttributedString yy_attachmentStringWithContent:imageView contentMode:UIViewContentModeScaleAspectFit attachmentSize:CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height) alignToFont:font alignment:YYTextVerticalAlignmentCenter]; //[微笑]17 对应的NSAttributedString 缓存到Dictionary中 [_cacheAttributedDictionary setObject:attrString forKey:keyFont]; return result; diff --git a/YuMi/Modules/YMMessage/View/Session/Content/MessageContentText.m b/YuMi/Modules/YMMessage/View/Session/Content/MessageContentText.m index e371bcc7..b654c4c5 100644 --- a/YuMi/Modules/YMMessage/View/Session/Content/MessageContentText.m +++ b/YuMi/Modules/YMMessage/View/Session/Content/MessageContentText.m @@ -64,7 +64,7 @@ model.message.rawAttachContent]; } QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper]; - NSMutableAttributedString * attribute = [faceManager attributedStringByText:messageText font:[UIFont systemFontOfSize:13]]; + NSMutableAttributedString * attribute = [faceManager attributedStringByText:messageText font:[UIFont systemFontOfSize:13] forMessageBubble:YES]; _messageText.attributedText = attribute; } [_messageText.superview layoutIfNeeded]; diff --git a/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageHeadlinesTextModel.m b/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageHeadlinesTextModel.m index 46de4ac3..43530042 100644 --- a/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageHeadlinesTextModel.m +++ b/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageHeadlinesTextModel.m @@ -48,7 +48,7 @@ CGSize dstRect = CGSizeMake(width, MAXFLOAT); QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper]; - NSMutableAttributedString * attribute = [faceManager attributedStringByText:messageText font:kFontMedium(14)]; + NSMutableAttributedString * attribute = [faceManager attributedStringByText:messageText font:kFontMedium(14) forMessageBubble:YES]; if(extModel.iosBubbleUrl.length > 0){ [attribute addAttributes:@{NSForegroundColorAttributeName: UIColorFromRGB(0x333333)} range:[attribute.string rangeOfString:attribute.string]]; }else{ diff --git a/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageTextModel.m b/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageTextModel.m index 049bd079..0dcd37ec 100644 --- a/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageTextModel.m +++ b/YuMi/Modules/YMMessage/View/Session/Content/SesssionModel/MessageTextModel.m @@ -34,7 +34,7 @@ } CGSize dstRect = CGSizeMake(CONTENT_WIDTH_MAX - MESSAGE_PADDING * 2, MAXFLOAT); QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper]; - NSMutableAttributedString * attribute = [faceManager attributedStringByText:messageText font:[UIFont systemFontOfSize:13]]; + NSMutableAttributedString * attribute = [faceManager attributedStringByText:messageText font:[UIFont systemFontOfSize:13] forMessageBubble:YES]; self.textAttribute = attribute; YYTextContainer *container = [YYTextContainer containerWithSize:dstRect]; container.maximumNumberOfRows = 0; diff --git a/YuMi/Modules/YMRoom/Features/Boom/RoomBoomManager.m b/YuMi/Modules/YMRoom/Features/Boom/RoomBoomManager.m index 45d819eb..8707aae8 100644 --- a/YuMi/Modules/YMRoom/Features/Boom/RoomBoomManager.m +++ b/YuMi/Modules/YMRoom/Features/Boom/RoomBoomManager.m @@ -266,8 +266,9 @@ if ([[XPSkillCardPlayerManager shareInstance] isInRoomVC]) { [self.boomEventsQueue addObject:attachment]; [[NSNotificationCenter defaultCenter] postNotificationName:@"UpdateWhenBoomExplosion" object:nil]; + [self.bannerEventsQueue addObject:attachment]; } - [self.bannerEventsQueue addObject:attachment]; +// [self.bannerEventsQueue addObject:attachment]; [self checkAndStartBoomEvent]; [self checkAndStartBannerEvent]; diff --git a/YuMi/Modules/YMTabbar/View/TabbarViewController.m b/YuMi/Modules/YMTabbar/View/TabbarViewController.m index 5a74b495..04b12b71 100644 --- a/YuMi/Modules/YMTabbar/View/TabbarViewController.m +++ b/YuMi/Modules/YMTabbar/View/TabbarViewController.m @@ -140,6 +140,9 @@ UIKIT_EXTERN NSString *kTabShowAnchorCardKey; [[NIMSDK sharedSDK].chatManager removeDelegate:self]; [[NIMSDK sharedSDK].systemNotificationManager removeDelegate:self]; [[NIMSDK sharedSDK].broadcastManager removeDelegate:self]; + + // 🔧 新增:清理 RoomBoomManager 监听器,防止内存泄漏 + [[RoomBoomManager sharedManager] removeEventListenerForTarget:self]; } - (void)viewDidLoad { @@ -186,10 +189,13 @@ UIKIT_EXTERN NSString *kTabShowAnchorCardKey; [[RoomBoomManager sharedManager] registerBoomBanner:^(id _Nonnull sth) { dispatch_async(dispatch_get_main_queue(), ^{ - [RoomBoomBannerAnimation display:kWindow - with:sth - tapToRoom:YES - complete:^{}]; + // 🔧 新增:检查用户是否在房间中,只有在房间中才显示全局火箭升级通知 + if ([XPSkillCardPlayerManager shareInstance].isInRoom == YES) { + [RoomBoomBannerAnimation display:kWindow + with:sth + tapToRoom:YES + complete:^{}]; + } }); } target:self]; diff --git a/YuMi/Structure/MVP/Presenter/BaseMvpPresenter.m b/YuMi/Structure/MVP/Presenter/BaseMvpPresenter.m index 0b710853..c24939e4 100644 --- a/YuMi/Structure/MVP/Presenter/BaseMvpPresenter.m +++ b/YuMi/Structure/MVP/Presenter/BaseMvpPresenter.m @@ -13,6 +13,7 @@ #import "BaseNavigationController.h" #import "FirstRechargeManager.h" #import "PublicRoomManager.h" +#import "RoomBoomManager.h" @interface BaseMvpPresenter() @@ -37,13 +38,16 @@ // 2. 重置公共房间管理器 [[PublicRoomManager sharedManager] reset]; - // 3. 数据logout + // 3. 清理房间火箭管理器状态 + [[RoomBoomManager sharedManager] leaveRoom]; + + // 4. 数据logout [[AccountInfoStorage instance] saveAccountInfo:nil]; [[AccountInfoStorage instance] saveTicket:nil]; if ([NIMSDK sharedSDK].loginManager.isLogined) { [[NIMSDK sharedSDK].loginManager logout:nil]; } - // 4. 跳登录页面 + // 5. 跳登录页面 [self tokenInvalid]; // ///关闭心跳 // [[ClientConfig shareConfig] resetHeartBratTimer];