Files
keyboard/keyBoard/Class/AiTalk/实现总结.md
2026-01-23 21:51:37 +08:00

9.4 KiB
Raw Blame History

聊天 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. 添加空消息占位
  2. 逐步更新文本
  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 文档
  • 快速参考卡片
  • 测试示例

🚀 下一步

  1. 测试新 UI

    • 运行 KBChatTestVC 查看效果
    • 验证所有功能
  2. 集成到 KBAiMainVC

    • 按照 集成指南.md 操作
    • 替换现有的 KBAiChatView
  3. 自定义样式(可选)

    • 修改气泡颜色
    • 调整圆角大小
    • 修改时间戳间隔
  4. 优化性能(可选)

    • 限制消息数量
    • 清除旧消息音频数据
    • 实现分页加载

完成!

你现在拥有一个功能完整、设计精美的聊天 UI 系统,完全符合你的需求:

  • 用户消息在右侧
  • AI 回复在左侧
  • AI 消息左上角有语音按钮
  • 对话中间显示时间
  • 使用 TableView Plain 模式
  • 三种独立 Cell 设计

祝你使用愉快! 🎉