9.4 KiB
9.4 KiB
聊天 UI 实现总结
✅ 已完成
根据你的需求,我已经完整实现了一个类似微信的聊天 UI 系统,包含以下功能:
核心功能
- ✅ 用户消息(右侧浅色气泡)
- ✅ AI 消息(左侧深色气泡)
- ✅ 语音播放按钮(AI 消息左上角)
- ✅ 语音时长显示(如 "6"")
- ✅ 时间戳(自动插入,5 分钟间隔)
- ✅ 打字机效果支持
- ✅ 自动滚动到底部
📁 创建的文件清单
1. Model(数据模型)
keyBoard/Class/AiTalk/M/
├── KBChatMessage.h # 消息模型头文件
└── KBChatMessage.m # 消息模型实现
功能:
- 支持三种消息类型:用户、AI、时间戳
- 包含文本、时间戳、语音时长、语音数据等属性
- 提供便捷构造方法
2. View(视图组件)
keyBoard/Class/AiTalk/V/
├── KBChatUserMessageCell.h # 用户消息 Cell 头文件
├── KBChatUserMessageCell.m # 用户消息 Cell 实现
├── KBChatAssistantMessageCell.h # AI 消息 Cell 头文件
├── KBChatAssistantMessageCell.m # AI 消息 Cell 实现
├── KBChatTimeCell.h # 时间戳 Cell 头文件
├── KBChatTimeCell.m # 时间戳 Cell 实现
├── KBChatTableView.h # 聊天列表视图头文件
└── KBChatTableView.m # 聊天列表视图实现
功能:
- KBChatUserMessageCell:右侧气泡,浅色背景
- KBChatAssistantMessageCell:左侧气泡,深色背景,带语音按钮
- KBChatTimeCell:居中显示时间
- KBChatTableView:主容器,管理所有消息和语音播放
3. ViewController(测试页面)
keyBoard/Class/AiTalk/VC/
├── KBChatTestVC.h # 测试页面头文件
└── KBChatTestVC.m # 测试页面实现
功能:
- 演示如何使用新的聊天 UI
- 提供添加消息、清空等测试按钮
- 加载模拟对话数据
4. 文档
keyBoard/Class/AiTalk/
├── 实现总结.md # 本文档
├── 集成指南.md # 详细集成步骤
└── V/
├── KBChatTableView_Usage.md # 使用说明
└── API_快速参考.md # API 快速查询
🏗️ 架构设计
方案选择:UITableView + Plain 模式
为什么选择 Plain 模式?
| 对比项 | Plain 模式 ✅ | Grouped 模式 ❌ |
|---|---|---|
| 视觉连贯性 | 消息紧密排列 | Section 间距打断视觉 |
| 时间戳处理 | 作为普通 Cell 灵活插入 | 需要用 Section Header |
| 数据管理 | 一维数组,简单 | 二维数组,复杂 |
| 性能 | Cell 复用简单 | Section 管理开销 |
| 符合习惯 | 微信、iMessage 都用此方案 | 不适合聊天场景 |
三种独立 Cell 设计
为什么不用一个通用 Cell?
✅ 三种独立 Cell 的优势:
- 职责清晰,每个 Cell 只负责一种样式
- 布局简单,不需要复杂的条件判断
- 复用标识符明确,性能好
- 易于维护和扩展
❌ 通用 Cell 的劣势:
- Cell 内部逻辑复杂,大量 if-else
- 布局约束需要动态调整,容易出错
- 复用时需要重置状态,性能略差
🎯 核心实现细节
1. 时间戳自动插入
策略:
- 第一条消息总是显示时间
- 距离上一条消息超过 5 分钟
- 跨天的消息
实现:
- (BOOL)shouldInsertTimestampForMessage:(KBChatMessage *)message {
if (self.messages.count == 0) return YES;
KBChatMessage *lastMessage = [self findLastNonTimeMessage];
NSTimeInterval interval = [message.timestamp timeIntervalSinceDate:lastMessage.timestamp];
if (interval >= kTimestampInterval) return YES;
// 检查是否跨天
return ![self isSameDay:message.timestamp with:lastMessage.timestamp];
}
2. 语音播放管理
功能:
- 点击播放/暂停
- 播放时图标切换
- 点击其他消息自动停止当前播放
- 播放完成自动恢复
实现:
- (void)assistantMessageCell:(KBChatAssistantMessageCell *)cell
didTapVoiceButtonForMessage:(KBChatMessage *)message {
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// 如果正在播放同一条,则暂停
if ([indexPath isEqual:self.playingCellIndexPath]) {
[self stopPlayingAudio];
return;
}
// 停止之前的播放
[self stopPlayingAudio];
// 播放新的音频
[self playAudioForMessage:message atIndexPath:indexPath];
}
3. 打字机效果
流程:
- 添加空消息占位
- 逐步更新文本
- 标记完成
实现:
// 1. 添加占位
[self.chatView addAssistantMessage:@"" audioDuration:0 audioData:nil];
// 2. 更新文本
[self.chatView updateLastAssistantMessage:currentText];
// 3. 完成
[self.chatView markLastAssistantMessageComplete];
4. 自动滚动
策略:
- 新消息添加后自动滚动到底部
- 使用动画效果
- 延迟 0.1 秒确保布局完成
实现:
- (void)reloadAndScroll {
[self.tableView reloadData];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self scrollToBottom];
});
}
📊 数据流
用户输入
↓
KBChatMessage (用户消息)
↓
判断是否需要时间戳
↓
插入时间戳 Cell(可选)
↓
插入用户消息 Cell
↓
刷新 TableView
↓
滚动到底部
↓
AI 处理
↓
KBChatMessage (AI 消息 + 音频)
↓
判断是否需要时间戳
↓
插入时间戳 Cell(可选)
↓
插入 AI 消息 Cell
↓
刷新 TableView
↓
滚动到底部
↓
用户点击语音按钮
↓
播放音频
🎨 UI 设计
用户消息(右侧)
┌─────────────┐
│ 你好呀。 │
└─────────────┘
- 背景色:
#F0F0F0(浅灰) - 文字颜色:黑色
- 对齐:右对齐
- 圆角:16pt
AI 消息(左侧)
▶️ 6"
┌─────────────────────────┐
│ (嘻嘻笑出声,不再逗你) │
│ 公子今天怎么一直在问好 │
│ 呀?是有什么开心的事情 │
│ 和我分享吗? │
└─────────────────────────┘
- 背景色:
rgba(0.2, 0.2, 0.2, 0.7)(深色半透明) - 文字颜色:白色
- 对齐:左对齐
- 圆角:16pt
- 语音按钮:左上角,24x24pt
时间戳(居中)
16:36
- 文字颜色:次要标签色
- 字体:12pt
- 对齐:居中
🔧 集成步骤(简化版)
1. 修改 import
#import "KBChatTableView.h"
2. 修改属性
@property (nonatomic, strong) KBChatTableView *chatView;
3. 初始化
self.chatView = [[KBChatTableView alloc] init];
4. 添加消息
// 用户消息
[self.chatView addUserMessage:text];
// AI 消息(带语音)
[self.chatView addAssistantMessage:text
audioDuration:duration
audioData:audioData];
详细步骤请查看:集成指南.md
📚 文档说明
1. 集成指南.md
- 完整的集成步骤
- 代码示例
- 常见问题解答
- 完成清单
2. KBChatTableView_Usage.md
- 详细的使用说明
- API 文档
- 自定义配置
- 注意事项
3. API_快速参考.md
- 快速查询 API
- 代码片段
- 常用配置
4. 实现总结.md(本文档)
- 架构设计说明
- 实现细节
- 文件清单
🧪 测试
运行测试页面
KBChatTestVC *testVC = [[KBChatTestVC alloc] init];
[self.navigationController pushViewController:testVC animated:YES];
测试功能
- ✅ 添加用户消息
- ✅ 添加 AI 消息
- ✅ 语音播放
- ✅ 时间戳显示
- ✅ 自动滚动
- ✅ 打字机效果
🎯 优势总结
1. 架构清晰
- 三种独立 Cell,职责明确
- Plain 模式,数据管理简单
- 代码易读易维护
2. 功能完整
- 支持文本、语音、时间戳
- 自动时间戳插入
- 语音播放管理
- 打字机效果
3. 性能优良
- Cell 复用机制
- 自动布局
- 流畅滚动
4. 易于扩展
- 可轻松添加新的消息类型
- 可自定义样式
- 可调整时间戳规则
5. 文档完善
- 详细的集成指南
- 完整的 API 文档
- 快速参考卡片
- 测试示例
🚀 下一步
-
测试新 UI
- 运行
KBChatTestVC查看效果 - 验证所有功能
- 运行
-
集成到 KBAiMainVC
- 按照
集成指南.md操作 - 替换现有的
KBAiChatView
- 按照
-
自定义样式(可选)
- 修改气泡颜色
- 调整圆角大小
- 修改时间戳间隔
-
优化性能(可选)
- 限制消息数量
- 清除旧消息音频数据
- 实现分页加载
✅ 完成!
你现在拥有一个功能完整、设计精美的聊天 UI 系统,完全符合你的需求:
- ✅ 用户消息在右侧
- ✅ AI 回复在左侧
- ✅ AI 消息左上角有语音按钮
- ✅ 对话中间显示时间
- ✅ 使用 TableView Plain 模式
- ✅ 三种独立 Cell 设计
祝你使用愉快! 🎉