428 lines
9.4 KiB
Markdown
428 lines
9.4 KiB
Markdown
# 聊天 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 分钟
|
||
- 跨天的消息
|
||
|
||
**实现:**
|
||
```objective-c
|
||
- (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. 语音播放管理
|
||
|
||
**功能:**
|
||
- 点击播放/暂停
|
||
- 播放时图标切换
|
||
- 点击其他消息自动停止当前播放
|
||
- 播放完成自动恢复
|
||
|
||
**实现:**
|
||
```objective-c
|
||
- (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. 添加空消息占位
|
||
2. 逐步更新文本
|
||
3. 标记完成
|
||
|
||
**实现:**
|
||
```objective-c
|
||
// 1. 添加占位
|
||
[self.chatView addAssistantMessage:@"" audioDuration:0 audioData:nil];
|
||
|
||
// 2. 更新文本
|
||
[self.chatView updateLastAssistantMessage:currentText];
|
||
|
||
// 3. 完成
|
||
[self.chatView markLastAssistantMessageComplete];
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 自动滚动
|
||
|
||
**策略:**
|
||
- 新消息添加后自动滚动到底部
|
||
- 使用动画效果
|
||
- 延迟 0.1 秒确保布局完成
|
||
|
||
**实现:**
|
||
```objective-c
|
||
- (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
|
||
```objective-c
|
||
#import "KBChatTableView.h"
|
||
```
|
||
|
||
### 2. 修改属性
|
||
```objective-c
|
||
@property (nonatomic, strong) KBChatTableView *chatView;
|
||
```
|
||
|
||
### 3. 初始化
|
||
```objective-c
|
||
self.chatView = [[KBChatTableView alloc] init];
|
||
```
|
||
|
||
### 4. 添加消息
|
||
```objective-c
|
||
// 用户消息
|
||
[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(本文档)
|
||
- 架构设计说明
|
||
- 实现细节
|
||
- 文件清单
|
||
|
||
---
|
||
|
||
## 🧪 测试
|
||
|
||
### 运行测试页面
|
||
|
||
```objective-c
|
||
KBChatTestVC *testVC = [[KBChatTestVC alloc] init];
|
||
[self.navigationController pushViewController:testVC animated:YES];
|
||
```
|
||
|
||
### 测试功能
|
||
- ✅ 添加用户消息
|
||
- ✅ 添加 AI 消息
|
||
- ✅ 语音播放
|
||
- ✅ 时间戳显示
|
||
- ✅ 自动滚动
|
||
- ✅ 打字机效果
|
||
|
||
---
|
||
|
||
## 🎯 优势总结
|
||
|
||
### 1. 架构清晰
|
||
- 三种独立 Cell,职责明确
|
||
- Plain 模式,数据管理简单
|
||
- 代码易读易维护
|
||
|
||
### 2. 功能完整
|
||
- 支持文本、语音、时间戳
|
||
- 自动时间戳插入
|
||
- 语音播放管理
|
||
- 打字机效果
|
||
|
||
### 3. 性能优良
|
||
- Cell 复用机制
|
||
- 自动布局
|
||
- 流畅滚动
|
||
|
||
### 4. 易于扩展
|
||
- 可轻松添加新的消息类型
|
||
- 可自定义样式
|
||
- 可调整时间戳规则
|
||
|
||
### 5. 文档完善
|
||
- 详细的集成指南
|
||
- 完整的 API 文档
|
||
- 快速参考卡片
|
||
- 测试示例
|
||
|
||
---
|
||
|
||
## 🚀 下一步
|
||
|
||
1. **测试新 UI**
|
||
- 运行 `KBChatTestVC` 查看效果
|
||
- 验证所有功能
|
||
|
||
2. **集成到 KBAiMainVC**
|
||
- 按照 `集成指南.md` 操作
|
||
- 替换现有的 `KBAiChatView`
|
||
|
||
3. **自定义样式**(可选)
|
||
- 修改气泡颜色
|
||
- 调整圆角大小
|
||
- 修改时间戳间隔
|
||
|
||
4. **优化性能**(可选)
|
||
- 限制消息数量
|
||
- 清除旧消息音频数据
|
||
- 实现分页加载
|
||
|
||
---
|
||
|
||
## ✅ 完成!
|
||
|
||
你现在拥有一个功能完整、设计精美的聊天 UI 系统,完全符合你的需求:
|
||
|
||
- ✅ 用户消息在右侧
|
||
- ✅ AI 回复在左侧
|
||
- ✅ AI 消息左上角有语音按钮
|
||
- ✅ 对话中间显示时间
|
||
- ✅ 使用 TableView Plain 模式
|
||
- ✅ 三种独立 Cell 设计
|
||
|
||
**祝你使用愉快!** 🎉
|