新增 QEmotionBoardView 表情不显示问题分析报告和排查报告,详细记录问题描述、代码逻辑、根因分析及解决方案。同时,修复 AppDelegate 中的图片加载逻辑,添加调试日志以便于后续排查,确保表情正常显示。
This commit is contained in:
143
QEmotionBoardView_问题分析报告.md
Normal file
143
QEmotionBoardView_问题分析报告.md
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
# QEmotionBoardView emoji 不显示问题分析报告
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
QEmotionBoardView 表情面板中的 emoji 表情无法正常显示,表情面板显示空白。
|
||||||
|
|
||||||
|
## 代码逻辑梳理
|
||||||
|
|
||||||
|
### 整体架构
|
||||||
|
QEmotionBoardView 是一个表情面板组件,主要包含以下几个核心类:
|
||||||
|
|
||||||
|
1. **QEmotionBoardView**: 主视图控制器,负责整体布局和事件处理
|
||||||
|
2. **UIEmotionPageView**: 表情页面视图,负责单个页面的表情渲染和交互
|
||||||
|
3. **UIEmotionVerticalScrollView**: 垂直滚动视图,包装页面视图
|
||||||
|
4. **QEmotion**: 表情数据模型
|
||||||
|
5. **QEmotionHelper**: 表情管理工具类
|
||||||
|
|
||||||
|
### 核心流程
|
||||||
|
|
||||||
|
#### 1. 表情数据加载流程
|
||||||
|
```
|
||||||
|
AppDelegate.initEmojiData()
|
||||||
|
→ 读取 emoji.plist
|
||||||
|
→ 创建 QEmotion 对象数组
|
||||||
|
→ 设置到 QEmotionHelper.emotionArray
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 表情面板显示流程
|
||||||
|
```
|
||||||
|
QEmotionBoardView 初始化
|
||||||
|
→ 设置 emotions 属性
|
||||||
|
→ layoutSubviews 触发布局
|
||||||
|
→ UIEmotionVerticalScrollView.setEmotions
|
||||||
|
→ UIEmotionPageView.layoutEmotionsIfNeeded
|
||||||
|
→ 创建 CALayer 显示表情图片
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. 表情渲染机制
|
||||||
|
- 使用 `CALayer` 而不是 `UIImageView` 来渲染表情,提高性能
|
||||||
|
- 通过 `emotionlayer.contents = (__bridge id)(self.emotions[i].image.CGImage)` 设置图片
|
||||||
|
- 计算每个表情的位置和点击区域
|
||||||
|
|
||||||
|
## 问题根因分析
|
||||||
|
|
||||||
|
### 主要问题:图片加载错误
|
||||||
|
|
||||||
|
在 `AppDelegate+ThirdConfig.m` 的 `initEmojiData` 方法中存在一个严重的 bug:
|
||||||
|
|
||||||
|
**错误代码:**
|
||||||
|
```objective-c
|
||||||
|
UIImage * image = [UIImage imageNamed:dic[@"file"]];
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题分析:**
|
||||||
|
1. `dic[@"file"]` 指向的是外层字典的 `file` 字段,但这个字段在 plist 中并不存在
|
||||||
|
2. 所有表情都尝试加载同一个不存在的图片文件
|
||||||
|
3. 导致所有 `QEmotion.image` 都为 `nil`
|
||||||
|
4. 在 `QEmotionBoardView` 中,`emotionlayer.contents` 被设置为 `nil`,所以表情不显示
|
||||||
|
|
||||||
|
**正确代码:**
|
||||||
|
```objective-c
|
||||||
|
NSDictionary * emotionDic = [emojiArray xpSafeObjectAtIndex:i];
|
||||||
|
UIImage * image = [UIImage imageNamed:emotionDic[@"file"]];
|
||||||
|
```
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 1. 修复图片加载逻辑
|
||||||
|
|
||||||
|
已修复 `AppDelegate+ThirdConfig.m` 中的图片加载逻辑:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
for (int i = 0; i < emojiArray.count; i++) {
|
||||||
|
NSDictionary * emotionDic = [emojiArray xpSafeObjectAtIndex:i];
|
||||||
|
if (!emotionDic) continue;
|
||||||
|
|
||||||
|
UIImage * image = [UIImage imageNamed:emotionDic[@"file"]];
|
||||||
|
QEmotion * info = [[QEmotion alloc] init];
|
||||||
|
|
||||||
|
info.displayName = emotionDic[@"tag"];
|
||||||
|
info.identifier = emotionDic[@"id"];
|
||||||
|
info.image = image;
|
||||||
|
|
||||||
|
[array addObject:info];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 添加调试代码
|
||||||
|
|
||||||
|
在关键位置添加了调试日志:
|
||||||
|
|
||||||
|
**AppDelegate 中:**
|
||||||
|
```objective-c
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"加载表情: %@, 图片: %@, 是否成功: %@", info.displayName, emotionDic[@"file"], image ? @"是" : @"否");
|
||||||
|
```
|
||||||
|
|
||||||
|
**QEmotionBoardView 中:**
|
||||||
|
```objective-c
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"QEmotionBoardView 设置表情数组,数量: %lu", (unsigned long)emotions.count);
|
||||||
|
for (int i = 0; i < MIN(emotions.count, 5); i++) {
|
||||||
|
QEmotion *emotion = emotions[i];
|
||||||
|
NSLog(@"表情 %d: %@, 图片: %@", i, emotion.displayName, emotion.image ? @"存在" : @"不存在");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**表情渲染中:**
|
||||||
|
```objective-c
|
||||||
|
// 添加调试日志
|
||||||
|
if (i < 3) { // 只打印前3个表情的调试信息
|
||||||
|
NSLog(@"渲染表情 %d: %@, 图片: %@, CGImage: %@", i, self.emotions[i].displayName,
|
||||||
|
self.emotions[i].image ? @"存在" : @"不存在",
|
||||||
|
self.emotions[i].image.CGImage ? @"存在" : @"不存在");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 验证图片文件
|
||||||
|
|
||||||
|
确认表情图片文件已正确添加到 Xcode 项目中:
|
||||||
|
- 图片文件位于 `YuMi/CustomUI/InputView/Emoji/` 目录
|
||||||
|
- 文件名格式为 `emoji_XX@2x.png`
|
||||||
|
- plist 中配置的文件名为 `emoji_XX.png`(iOS 会自动处理 @2x 后缀)
|
||||||
|
- 所有图片文件都已添加到项目的 Bundle Resources 中
|
||||||
|
|
||||||
|
## 测试验证
|
||||||
|
|
||||||
|
修复后,可以通过以下方式验证:
|
||||||
|
|
||||||
|
1. **查看控制台日志**:运行应用后查看控制台输出,确认:
|
||||||
|
- 表情数组加载完成,数量正确
|
||||||
|
- 每个表情的图片加载成功
|
||||||
|
- QEmotionBoardView 正确设置表情数组
|
||||||
|
- 表情渲染时图片和 CGImage 都存在
|
||||||
|
|
||||||
|
2. **功能测试**:
|
||||||
|
- 打开表情面板,确认表情正常显示
|
||||||
|
- 点击表情,确认能正常插入到输入框
|
||||||
|
- 测试删除和发送功能
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
问题的根本原因是 AppDelegate 中图片加载逻辑的错误,导致所有表情的图片都为 nil。修复后,表情应该能正常显示。如果仍有问题,可以通过添加的调试日志进一步排查。
|
||||||
|
|
175
QEmotionBoardView_问题排查报告.md
Normal file
175
QEmotionBoardView_问题排查报告.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
# QEmotionBoardView emoji 不显示问题排查报告
|
||||||
|
|
||||||
|
## 问题现状
|
||||||
|
|
||||||
|
- 表情数组已成功加载(125个表情)
|
||||||
|
- 表情图片文件存在且正确
|
||||||
|
- 但表情面板仍然不显示 emoji
|
||||||
|
|
||||||
|
## 排查过程
|
||||||
|
|
||||||
|
### 1. 数据流验证
|
||||||
|
|
||||||
|
已添加调试代码验证数据流:
|
||||||
|
|
||||||
|
- AppDelegate 中表情数组加载完成
|
||||||
|
- QEmotionBoardView 设置表情数组
|
||||||
|
- UIEmotionVerticalScrollView 接收表情数据
|
||||||
|
- UIEmotionPageView 接收表情数据
|
||||||
|
|
||||||
|
### 2. 关键问题发现
|
||||||
|
|
||||||
|
#### 问题1:UIEmotionVerticalScrollView bounds 可能为0
|
||||||
|
|
||||||
|
在 `UIEmotionVerticalScrollView.setEmotions` 方法中:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
CGSize contentSize = CGSizeMake(self.bounds.size.width - [self edgeInsetsGetHorizontalValue:paddingInPage],
|
||||||
|
self.bounds.size.height - [self edgeInsetsGetVerticalValue:paddingInPage]);
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题分析:**
|
||||||
|
|
||||||
|
- 当调用 `setEmotions` 时,UIEmotionVerticalScrollView 可能还没有正确的 bounds
|
||||||
|
- 如果 bounds 为 0,contentSize 也会为 0
|
||||||
|
- 导致 `emotionCountPerRow` 计算错误
|
||||||
|
- 最终影响表情的布局和显示
|
||||||
|
|
||||||
|
#### 问题2:布局时机问题
|
||||||
|
|
||||||
|
UIEmotionVerticalScrollView 的 frame 设置时机可能有问题:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
CGSize size = [pageView verticalSizeThatFits:self.bounds.size emotionVerticalSpacing:emotionVerticalSpacing];
|
||||||
|
self.pageView.frame = CGRectMake(0, 0, size.width, size.height);
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题分析:**
|
||||||
|
|
||||||
|
- 如果 `self.bounds.size` 为 0,计算出的 size 也会有问题
|
||||||
|
- pageView 的 frame 可能设置不正确
|
||||||
|
- 导致表情无法正确显示
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 方案1:延迟设置表情数据
|
||||||
|
|
||||||
|
在 QEmotionBoardView 的 layoutSubviews 中设置表情数据,确保 bounds 已经正确:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
- (void)layoutSubviews {
|
||||||
|
[super layoutSubviews];
|
||||||
|
|
||||||
|
// 确保 bounds 已经设置
|
||||||
|
if (CGRectIsEmpty(self.bounds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置表情数据
|
||||||
|
if (self.emotions && self.emotions.count > 0) {
|
||||||
|
[self.verticalScrollView setEmotions:self.emotions
|
||||||
|
emotionSize:self.emotionSize
|
||||||
|
minimumEmotionHorizontalSpacing:self.minimumEmotionHorizontalSpacing
|
||||||
|
emotionVerticalSpacing:self.emotionVerticalSpacing
|
||||||
|
emotionSelectedBackgroundExtension:self.emotionSelectedBackgroundExtension
|
||||||
|
paddingInPage:self.paddingInPage];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其他布局代码...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案2:修复 UIEmotionVerticalScrollView 的 bounds 问题
|
||||||
|
|
||||||
|
在 setEmotions 方法中添加 bounds 检查:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
- (void)setEmotions:(NSArray<QEmotion *> *)emotions
|
||||||
|
emotionSize:(CGSize)emotionSize
|
||||||
|
minimumEmotionHorizontalSpacing:(CGFloat)minimumEmotionHorizontalSpacing
|
||||||
|
emotionVerticalSpacing:(CGFloat)emotionVerticalSpacing
|
||||||
|
emotionSelectedBackgroundExtension:(UIEdgeInsets)emotionSelectedBackgroundExtension
|
||||||
|
paddingInPage:(UIEdgeInsets)paddingInPage {
|
||||||
|
|
||||||
|
// 检查 bounds 是否有效
|
||||||
|
if (CGRectIsEmpty(self.bounds)) {
|
||||||
|
NSLog(@"UIEmotionVerticalScrollView bounds 为空,延迟设置表情");
|
||||||
|
// 延迟到下一个运行循环
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self setEmotions:emotions
|
||||||
|
emotionSize:emotionSize
|
||||||
|
minimumEmotionHorizontalSpacing:minimumEmotionHorizontalSpacing
|
||||||
|
emotionVerticalSpacing:emotionVerticalSpacing
|
||||||
|
emotionSelectedBackgroundExtension:emotionSelectedBackgroundExtension
|
||||||
|
paddingInPage:paddingInPage];
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 原有的设置逻辑...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 方案3:使用固定尺寸
|
||||||
|
|
||||||
|
如果 bounds 问题无法解决,可以使用固定的 contentSize:
|
||||||
|
|
||||||
|
```objective-c
|
||||||
|
- (void)setEmotions:(NSArray<QEmotion *> *)emotions
|
||||||
|
emotionSize:(CGSize)emotionSize
|
||||||
|
minimumEmotionHorizontalSpacing:(CGFloat)minimumEmotionHorizontalSpacing
|
||||||
|
emotionVerticalSpacing:(CGFloat)emotionVerticalSpacing
|
||||||
|
emotionSelectedBackgroundExtension:(UIEdgeInsets)emotionSelectedBackgroundExtension
|
||||||
|
paddingInPage:(UIEdgeInsets)paddingInPage {
|
||||||
|
|
||||||
|
UIEmotionPageView *pageView = self.pageView;
|
||||||
|
pageView.emotions = emotions;
|
||||||
|
pageView.padding = paddingInPage;
|
||||||
|
|
||||||
|
// 使用父视图的宽度作为基准
|
||||||
|
CGFloat availableWidth = self.superview ? self.superview.bounds.size.width : 320;
|
||||||
|
CGSize contentSize = CGSizeMake(availableWidth - [self edgeInsetsGetHorizontalValue:paddingInPage],
|
||||||
|
self.bounds.size.height - [self edgeInsetsGetVerticalValue:paddingInPage]);
|
||||||
|
|
||||||
|
// 其他逻辑...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 调试建议
|
||||||
|
|
||||||
|
### 1. 运行应用并查看日志
|
||||||
|
|
||||||
|
运行应用后,查看控制台输出,特别关注:
|
||||||
|
|
||||||
|
- UIEmotionVerticalScrollView bounds 是否为 0
|
||||||
|
- contentSize 计算是否正确
|
||||||
|
- emotionCountPerRow 和 numberOfRows 的值
|
||||||
|
|
||||||
|
### 2. 检查布局时机
|
||||||
|
|
||||||
|
在 Xcode 中使用 View Debugger 检查:
|
||||||
|
|
||||||
|
- QEmotionBoardView 的 frame 是否正确
|
||||||
|
- UIEmotionVerticalScrollView 的 frame 是否正确
|
||||||
|
- UIEmotionPageView 的 frame 是否正确
|
||||||
|
|
||||||
|
### 3. 验证表情渲染
|
||||||
|
|
||||||
|
检查 CALayer 是否正确创建:
|
||||||
|
|
||||||
|
- emotionLayers 数组是否有内容
|
||||||
|
- 每个 layer 的 frame 是否正确
|
||||||
|
- layer 的 contents 是否设置
|
||||||
|
|
||||||
|
## 预期结果
|
||||||
|
|
||||||
|
修复后,应该能看到:
|
||||||
|
|
||||||
|
1. 控制台日志显示正确的 bounds 和 contentSize
|
||||||
|
2. 表情面板正常显示 emoji
|
||||||
|
3. 表情可以正常点击和选择
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
主要问题是 UIEmotionVerticalScrollView 在设置表情数据时,bounds 可能还没有正确设置,导致布局计算错误。通过延迟设置或使用有效的尺寸基准可以解决这个问题。
|
||||||
|
|
@@ -161,22 +161,31 @@ UIKIT_EXTERN NSString * adImageName;
|
|||||||
NSMutableArray * array = [NSMutableArray array];
|
NSMutableArray * array = [NSMutableArray array];
|
||||||
for (int i = 0; i < emojiArray.count; i++) {
|
for (int i = 0; i < emojiArray.count; i++) {
|
||||||
|
|
||||||
UIImage * image = [UIImage imageNamed:dic[@"file"]];
|
NSDictionary * emotionDic = [emojiArray xpSafeObjectAtIndex:i];
|
||||||
|
if (!emotionDic) continue;
|
||||||
|
|
||||||
|
UIImage * image = [UIImage imageNamed:emotionDic[@"file"]];
|
||||||
QEmotion * info = [[QEmotion alloc] init];
|
QEmotion * info = [[QEmotion alloc] init];
|
||||||
|
|
||||||
NSDictionary * dic = [emojiArray xpSafeObjectAtIndex:i];
|
info.displayName = emotionDic[@"tag"];
|
||||||
if (dic) {
|
info.identifier = emotionDic[@"id"];
|
||||||
info.displayName = dic[@"tag"];
|
|
||||||
info.identifier = dic[@"id"];
|
|
||||||
}
|
|
||||||
|
|
||||||
info.image = image;
|
info.image = image;
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"加载表情: %@, 图片: %@, 是否成功: %@", info.displayName, emotionDic[@"file"], image ? @"是" : @"否");
|
||||||
|
|
||||||
[array addObject:info];
|
[array addObject:info];
|
||||||
}
|
}
|
||||||
//在这里强烈建议先预加载一下表情
|
//在这里强烈建议先预加载一下表情
|
||||||
QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper];
|
QEmotionHelper *faceManager = [QEmotionHelper sharedEmotionHelper];
|
||||||
faceManager.emotionArray = array;
|
faceManager.emotionArray = array;
|
||||||
|
|
||||||
|
// 测试图片加载
|
||||||
|
NSLog(@"表情数组加载完成,总数: %lu", (unsigned long)array.count);
|
||||||
|
for (int i = 0; i < MIN(array.count, 3); i++) {
|
||||||
|
QEmotion *emotion = array[i];
|
||||||
|
NSLog(@"测试表情 %d: %@, 图片: %@", i, emotion.displayName, emotion.image ? @"加载成功" : @"加载失败");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -128,3 +128,4 @@
|
|||||||
<Emoticon ID="emoticon_emoji_115" Tag="[自行车]" File="emoji_115.png" />
|
<Emoticon ID="emoticon_emoji_115" Tag="[自行车]" File="emoji_115.png" />
|
||||||
</Catalog>
|
</Catalog>
|
||||||
</PopoEmoticons>
|
</PopoEmoticons>
|
||||||
|
˜
|
||||||
|
@@ -111,6 +111,10 @@ const int UISendButtonHeight = 41;
|
|||||||
if (isSizeChanged) {
|
if (isSizeChanged) {
|
||||||
[self setNeedsLayoutEmotions];
|
[self setNeedsLayoutEmotions];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"UIEmotionPageView layoutSubviews: frame=%@, needsLayoutEmotions=%d", NSStringFromCGRect(self.frame), self.needsLayoutEmotions);
|
||||||
|
|
||||||
[self layoutEmotionsIfNeeded];
|
[self layoutEmotionsIfNeeded];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +124,14 @@ const int UISendButtonHeight = 41;
|
|||||||
|
|
||||||
- (void)setEmotions:(NSArray<QEmotion *> *)emotions {
|
- (void)setEmotions:(NSArray<QEmotion *> *)emotions {
|
||||||
if ([_emotions isEqualToArray:emotions]) return;
|
if ([_emotions isEqualToArray:emotions]) return;
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"UIEmotionPageView setEmotions: 表情数量=%lu", (unsigned long)emotions.count);
|
||||||
|
if (emotions.count > 0) {
|
||||||
|
QEmotion *firstEmotion = emotions[0];
|
||||||
|
NSLog(@"UIEmotionPageView 第一个表情: %@, 图片: %@", firstEmotion.displayName, firstEmotion.image ? @"存在" : @"不存在");
|
||||||
|
}
|
||||||
|
|
||||||
_emotions = emotions;
|
_emotions = emotions;
|
||||||
[self setNeedsLayoutEmotions];
|
[self setNeedsLayoutEmotions];
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
@@ -156,6 +168,13 @@ const int UISendButtonHeight = 41;
|
|||||||
}
|
}
|
||||||
|
|
||||||
emotionlayer.contents = (__bridge id)(self.emotions[i].image.CGImage);//使用layer效率更高
|
emotionlayer.contents = (__bridge id)(self.emotions[i].image.CGImage);//使用layer效率更高
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
if (i < 3) { // 只打印前3个表情的调试信息
|
||||||
|
NSLog(@"渲染表情 %ld: %@, 图片: %@, CGImage: %@", (long)i, self.emotions[i].displayName,
|
||||||
|
self.emotions[i].image ? @"存在" : @"不存在",
|
||||||
|
self.emotions[i].image.CGImage ? @"存在" : @"不存在");
|
||||||
|
}
|
||||||
NSInteger row = i / emotionCountPerRow;
|
NSInteger row = i / emotionCountPerRow;
|
||||||
emotionOrigin.x = self.padding.left + (self.emotionSize.width + emotionHorizontalSpacing) * (i % emotionCountPerRow);
|
emotionOrigin.x = self.padding.left + (self.emotionSize.width + emotionHorizontalSpacing) * (i % emotionCountPerRow);
|
||||||
emotionOrigin.y = self.padding.top + (self.emotionSize.height + emotionVerticalSpacing) * row;
|
emotionOrigin.y = self.padding.top + (self.emotionSize.height + emotionVerticalSpacing) * row;
|
||||||
@@ -246,12 +265,29 @@ const int UISendButtonHeight = 41;
|
|||||||
emotionVerticalSpacing:(CGFloat)emotionVerticalSpacing
|
emotionVerticalSpacing:(CGFloat)emotionVerticalSpacing
|
||||||
emotionSelectedBackgroundExtension:(UIEdgeInsets)emotionSelectedBackgroundExtension
|
emotionSelectedBackgroundExtension:(UIEdgeInsets)emotionSelectedBackgroundExtension
|
||||||
paddingInPage:(UIEdgeInsets)paddingInPage {
|
paddingInPage:(UIEdgeInsets)paddingInPage {
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"UIEmotionVerticalScrollView setEmotions: 表情数量=%lu, emotionSize=%@", (unsigned long)emotions.count, NSStringFromCGSize(emotionSize));
|
||||||
|
if (emotions.count > 0) {
|
||||||
|
QEmotion *firstEmotion = emotions[0];
|
||||||
|
NSLog(@"第一个表情: %@, 图片: %@", firstEmotion.displayName, firstEmotion.image ? @"存在" : @"不存在");
|
||||||
|
}
|
||||||
|
|
||||||
UIEmotionPageView *pageView = self.pageView;
|
UIEmotionPageView *pageView = self.pageView;
|
||||||
pageView.emotions = emotions;
|
pageView.emotions = emotions;
|
||||||
pageView.padding = paddingInPage;
|
pageView.padding = paddingInPage;
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"UIEmotionVerticalScrollView bounds: %@", NSStringFromCGRect(self.bounds));
|
||||||
|
NSLog(@"UIEmotionVerticalScrollView paddingInPage: %@", NSStringFromUIEdgeInsets(paddingInPage));
|
||||||
|
|
||||||
CGSize contentSize = CGSizeMake(self.bounds.size.width - [self edgeInsetsGetHorizontalValue:paddingInPage], self.bounds.size.height - [self edgeInsetsGetVerticalValue:paddingInPage]);
|
CGSize contentSize = CGSizeMake(self.bounds.size.width - [self edgeInsetsGetHorizontalValue:paddingInPage], self.bounds.size.height - [self edgeInsetsGetVerticalValue:paddingInPage]);
|
||||||
|
NSLog(@"UIEmotionVerticalScrollView contentSize: %@", NSStringFromCGSize(contentSize));
|
||||||
|
|
||||||
NSInteger emotionCountPerRow = (contentSize.width + minimumEmotionHorizontalSpacing) / (emotionSize.width + minimumEmotionHorizontalSpacing);
|
NSInteger emotionCountPerRow = (contentSize.width + minimumEmotionHorizontalSpacing) / (emotionSize.width + minimumEmotionHorizontalSpacing);
|
||||||
pageView.numberOfRows = ceil(emotions.count / (CGFloat)emotionCountPerRow);
|
pageView.numberOfRows = ceil(emotions.count / (CGFloat)emotionCountPerRow);
|
||||||
|
|
||||||
|
NSLog(@"UIEmotionVerticalScrollView emotionCountPerRow: %ld, numberOfRows: %ld", (long)emotionCountPerRow, (long)pageView.numberOfRows);
|
||||||
pageView.emotionSize =emotionSize;
|
pageView.emotionSize =emotionSize;
|
||||||
pageView.emotionSelectedBackgroundExtension = emotionSelectedBackgroundExtension;
|
pageView.emotionSelectedBackgroundExtension = emotionSelectedBackgroundExtension;
|
||||||
pageView.minimumEmotionHorizontalSpacing = minimumEmotionHorizontalSpacing;
|
pageView.minimumEmotionHorizontalSpacing = minimumEmotionHorizontalSpacing;
|
||||||
@@ -370,6 +406,14 @@ const int UISendButtonHeight = 41;
|
|||||||
|
|
||||||
- (void)setEmotions:(NSArray<QEmotion *> *)emotions {
|
- (void)setEmotions:(NSArray<QEmotion *> *)emotions {
|
||||||
_emotions = emotions;
|
_emotions = emotions;
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
NSLog(@"QEmotionBoardView 设置表情数组,数量: %lu", (unsigned long)emotions.count);
|
||||||
|
for (int i = 0; i < MIN(emotions.count, 5); i++) {
|
||||||
|
QEmotion *emotion = emotions[i];
|
||||||
|
NSLog(@"表情 %d: %@, 图片: %@", i, emotion.displayName, emotion.image ? @"存在" : @"不存在");
|
||||||
|
}
|
||||||
|
|
||||||
[self setNeedsLayout];
|
[self setNeedsLayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -808,6 +808,8 @@ typedef NS_ENUM(NSUInteger, CustomMessageTypeRoomLevelUpdate) {
|
|||||||
|
|
||||||
@property(nonatomic, assign) NSInteger seq; // 本地序号,用于将一条消息分解为多条有次序的消息
|
@property(nonatomic, assign) NSInteger seq; // 本地序号,用于将一条消息分解为多条有次序的消息
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isFromPublic;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
@property (nonatomic, copy) NSString *currentUserId;
|
@property (nonatomic, copy) NSString *currentUserId;
|
||||||
@property (nonatomic, strong) UserInfoModel *userInfo;
|
@property (nonatomic, strong) UserInfoModel *userInfo;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation PublicRoomManager
|
@implementation PublicRoomManager
|
||||||
@@ -217,6 +219,7 @@
|
|||||||
NSMutableDictionary *ext = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary
|
NSMutableDictionary *ext = [NSMutableDictionary dictionaryWithObject:extModel.model2dictionary
|
||||||
forKey:[NSString stringWithFormat:@"%ld", self.userInfo.uid]];
|
forKey:[NSString stringWithFormat:@"%ld", self.userInfo.uid]];
|
||||||
request.roomExt = [ext toJSONString];
|
request.roomExt = [ext toJSONString];
|
||||||
|
request.retryCount = 3;
|
||||||
|
|
||||||
// 进入房间
|
// 进入房间
|
||||||
@kWeakify(self);
|
@kWeakify(self);
|
||||||
@@ -373,6 +376,10 @@
|
|||||||
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
|
- (void)onRecvMessages:(NSArray<NIMMessage *> *)messages {
|
||||||
// 只处理公共房间的消息
|
// 只处理公共房间的消息
|
||||||
for (NIMMessage *message in messages) {
|
for (NIMMessage *message in messages) {
|
||||||
|
if ([message.session.sessionId isEqualToString:self.currentPublicRoomId]) {
|
||||||
|
[self handleMessageWithAttachmentAndFirstSecond:message];
|
||||||
|
}
|
||||||
|
/*
|
||||||
if (message.session.sessionType == NIMSessionTypeChatroom) {
|
if (message.session.sessionType == NIMSessionTypeChatroom) {
|
||||||
NSString *sessionId = message.session.sessionId;
|
NSString *sessionId = message.session.sessionId;
|
||||||
if ([sessionId isEqualToString:self.currentPublicRoomId]) {
|
if ([sessionId isEqualToString:self.currentPublicRoomId]) {
|
||||||
@@ -382,6 +389,7 @@
|
|||||||
NIMCustomObject *obj = (NIMCustomObject *) message.messageObject;
|
NIMCustomObject *obj = (NIMCustomObject *) message.messageObject;
|
||||||
attachment = (AttachmentModel *) obj.attachment;
|
attachment = (AttachmentModel *) obj.attachment;
|
||||||
if (attachment.first > 0 && attachment.second >0) {
|
if (attachment.first > 0 && attachment.second >0) {
|
||||||
|
attachment.isFromPublic = YES;
|
||||||
[self handleMessageWithAttachmentAndFirstSecond:message];
|
[self handleMessageWithAttachmentAndFirstSecond:message];
|
||||||
}
|
}
|
||||||
// if (attachment) {
|
// if (attachment) {
|
||||||
@@ -402,11 +410,18 @@
|
|||||||
// messageExt.roomExt);
|
// messageExt.roomExt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleMessageWithAttachmentAndFirstSecond:(NIMMessage *)message {
|
- (void)handleMessageWithAttachmentAndFirstSecond:(NIMMessage *)message {
|
||||||
|
// 只有用户在房间时,才会转发
|
||||||
|
if (![XPSkillCardPlayerManager shareInstance].isInRoom) {
|
||||||
|
NSLog(@"PublicRoomManager: 用户未在房间中,跳过消息转发");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"MessageFromPublicRoomWithAttachmentNotification"
|
||||||
|
object:message];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handleFirst_106:(AttachmentModel *)attachment
|
- (void)handleFirst_106:(AttachmentModel *)attachment
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
#import "XPMessageRemoteExtModel.h"
|
#import "XPMessageRemoteExtModel.h"
|
||||||
|
|
||||||
// 公共房间消息转发通知名称
|
// 公共房间消息转发通知名称
|
||||||
UIKIT_EXTERN NSString * const kMessageFromPublicRoomWithAttachmentNotification;
|
UIKIT_EXTERN NSString * _Nullable const kMessageFromPublicRoomWithAttachmentNotification;
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@@ -1932,9 +1932,21 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (![message.session.sessionId isEqualToString:@(self.roomInfo.roomId).stringValue]) {
|
if (![message.session.sessionId isEqualToString:@(self.roomInfo.roomId).stringValue]) {
|
||||||
NSLog(@"[Recv] ⛔️ 过滤:房间不匹配 | msg.sid=%@ | curRoomId=%@",
|
// if (message.messageType == NIMMessageTypeCustom) {
|
||||||
message.session.sessionId, @(self.roomInfo.roomId).stringValue);
|
// NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||||||
continue;
|
// if ([obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||||||
|
// AttachmentModel *att = (AttachmentModel *)obj.attachment;
|
||||||
|
// if (!att.isFromPublic) {
|
||||||
|
// NSLog(@"[Recv] ⛔️ 过滤:房间不匹配 | msg.sid=%@ | curRoomId=%@",
|
||||||
|
// message.session.sessionId, @(self.roomInfo.roomId).stringValue);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }else {
|
||||||
|
NSLog(@"[Recv] ⛔️ 过滤:房间不匹配 | msg.sid=%@ | curRoomId=%@",
|
||||||
|
message.session.sessionId, @(self.roomInfo.roomId).stringValue);
|
||||||
|
continue;
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"[Recv] --- Message Raw Attach Content: %@, %@, %ld", @(message.senderClientType), message.rawAttachContent, (long)message.messageType);
|
NSLog(@"[Recv] --- Message Raw Attach Content: %@, %@, %ld", @(message.senderClientType), message.rawAttachContent, (long)message.messageType);
|
||||||
@@ -1948,19 +1960,19 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
|||||||
[self handleNIMNotificationTypeMessage:message];
|
[self handleNIMNotificationTypeMessage:message];
|
||||||
} else if (message.messageType == NIMMessageTypeCustom) {
|
} else if (message.messageType == NIMMessageTypeCustom) {
|
||||||
// 自定义消息排查日志:first/second/size3
|
// 自定义消息排查日志:first/second/size3
|
||||||
//#if DEBUG
|
#if DEBUG
|
||||||
// if ([message.messageObject isKindOfClass:[NIMCustomObject class]]) {
|
if ([message.messageObject isKindOfClass:[NIMCustomObject class]]) {
|
||||||
// NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
NIMCustomObject *obj = (NIMCustomObject *)message.messageObject;
|
||||||
// if ([obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
if ([obj.attachment isKindOfClass:[AttachmentModel class]]) {
|
||||||
// AttachmentModel *att = (AttachmentModel *)obj.attachment;
|
AttachmentModel *att = (AttachmentModel *)obj.attachment;
|
||||||
// NSData *payloadJSON = nil;
|
NSData *payloadJSON = nil;
|
||||||
// @try { payloadJSON = [NSJSONSerialization dataWithJSONObject:att.data ?: @{} options:0 error:nil]; } @catch (__unused NSException *e) {}
|
@try { payloadJSON = [NSJSONSerialization dataWithJSONObject:att.data ?: @{} options:0 error:nil]; } @catch (__unused NSException *e) {}
|
||||||
// NSLog(@"[Recv] 🎯 自定义消息 | first=%ld second=%ld | payload=%lub | sid=%@ | ts=%.3f",
|
NSLog(@"[Recv] 🎯 自定义消息 | first=%ld second=%ld | payload=%lub | sid=%@ | ts=%.3f",
|
||||||
// (long)att.first, (long)att.second, (unsigned long)payloadJSON.length,
|
(long)att.first, (long)att.second, (unsigned long)payloadJSON.length,
|
||||||
// message.session.sessionId, [[NSDate date] timeIntervalSince1970]);
|
message.session.sessionId, [[NSDate date] timeIntervalSince1970]);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//#endif
|
#endif
|
||||||
[self handleNimCustomTypeMessage:message];
|
[self handleNimCustomTypeMessage:message];
|
||||||
} else if(message.messageType == NIMMessageTypeText) {
|
} else if(message.messageType == NIMMessageTypeText) {
|
||||||
[self.messageContainerView handleNIMTextMessage:message];
|
[self.messageContainerView handleNIMTextMessage:message];
|
||||||
@@ -3239,9 +3251,32 @@ XPCandyTreeInsufficientBalanceViewDelegate>
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 使用现有的消息处理流程
|
// 使用现有的消息处理流程
|
||||||
[self.messageContainerView handleNIMCustomMessage:message];
|
// [self.messageContainerView handleNIMCustomMessage:message];
|
||||||
|
// [self.animationView handleNIMCustomMessage:message];
|
||||||
|
// [self handleNimCustomTypeMessage:message];
|
||||||
|
// [self onRecvMessages:@[message]];
|
||||||
|
|
||||||
|
|
||||||
NSLog(@"XPRoomViewController: 处理公共房间转发的106类型消息");
|
switch (message.messageType) {
|
||||||
|
case NIMMessageTypeNotification:
|
||||||
|
[self handleNIMNotificationTypeMessage:message];
|
||||||
|
break;
|
||||||
|
case NIMMessageTypeCustom:
|
||||||
|
[self handleNimCustomTypeMessage:message];
|
||||||
|
break;
|
||||||
|
case NIMMessageTypeText:
|
||||||
|
[self.messageContainerView handleNIMTextMessage:message];
|
||||||
|
[self.littleGameView handleNIMTextMessage:message];
|
||||||
|
break;
|
||||||
|
case NIMMessageTypeTip:
|
||||||
|
[self.messageContainerView handleNIMTextMessage:message];
|
||||||
|
break;
|
||||||
|
case NIMMessageTypeImage:
|
||||||
|
[self.messageContainerView handleNIMImageMessage:message];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Reference in New Issue
Block a user