7.1 KiB
7.1 KiB
人设列表实现说明
📦 架构概览
KBAIHomeVC (人设列表容器)
└─ UICollectionView (竖向分页滚动)
└─ KBPersonaChatCell (每个人设占满屏)
├─ 背景图(coverImageUrl)
├─ 头像(avatarUrl)
├─ 人设名称(name)
├─ 简介(shortDesc)
└─ UITableView (聊天记录 - 待实现)
📂 文件结构
Model 层(keyBoard/Class/AiTalk/M/)
-
KBPersonaModel.h/m:人设模型
- 包含:personaId、name、avatarUrl、coverImageUrl、shortDesc、introText 等
- 扩展属性:tagsArray、isEnabled、isPublic
-
KBPersonaPageModel.h/m:分页数据模型
- 包含:records(人设数组)、total、current、pages、hasMore
View 层(keyBoard/Class/AiTalk/V/)
- KBPersonaChatCell.h/m:人设聊天 Cell
- 展示:背景图、头像、名称、简介
- 支持:预加载数据
VM 层(keyBoard/Class/AiTalk/VM/)
- AiVM.h/m:网络请求管理
- 新增接口:
fetchPersonasWithPageNum:pageSize:completion: - 请求地址:
POST /ai-companion/page
- 新增接口:
VC 层(keyBoard/Class/AiTalk/VC/)
- KBAIHomeVC.h/m:人设列表容器
- 功能:分页加载、竖向翻页、预加载相邻 Cell
🔧 核心功能
1. 竖向分页滚动
// UICollectionView 配置
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.itemSize = [UIScreen mainScreen].bounds.size; // 每个 cell 占满屏
_collectionView.pagingEnabled = YES; // 开启分页
2. 预加载机制
- 预加载 3 个 Cell:上一个、当前、下一个
- 触发时机:滑动超过 30% 时开始预加载
- 避免重复:用
preloadedIndexes记录已加载的索引
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageHeight = scrollView.bounds.size.height;
CGFloat offsetY = scrollView.contentOffset.y;
NSInteger currentPage = offsetY / pageHeight;
// 滑动超过 30% 就预加载
if (fmod(offsetY, pageHeight) > pageHeight * 0.3) {
[self preloadAdjacentCellsForIndex:currentPage + 1];
}
}
3. 分页加载
- 首次加载:pageNum=1, pageSize=10
- 加载更多:接近底部时自动加载下一页
- 防重复:用
isLoading标记防止重复请求
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 接近底部时加载更多
if (offsetY + scrollView.bounds.size.height >= scrollView.contentSize.height - pageHeight) {
[self loadMorePersonas];
}
}
🌐 网络请求
接口地址
POST /ai-companion/page
请求参数
{
"pageNum": 1,
"pageSize": 10
}
响应格式
{
"code": 0,
"message": "success",
"data": {
"records": [
{
"id": 1,
"name": "温柔小姐姐",
"avatarUrl": "https://...",
"coverImageUrl": "https://...",
"shortDesc": "温柔体贴的聊天伙伴",
"introText": "你好呀,今天过得怎么样?",
"personalityTags": "温柔,体贴,善解人意",
...
}
],
"total": 100,
"current": 1,
"pages": 10
}
}
使用示例
[self.aiVM fetchPersonasWithPageNum:1
pageSize:10
completion:^(KBPersonaPageModel *pageModel, NSError *error) {
if (error) {
NSLog(@"加载失败:%@", error.localizedDescription);
return;
}
[self.personas addObjectsFromArray:pageModel.records];
self.hasMore = pageModel.hasMore;
[self.collectionView reloadData];
}];
🎨 UI 布局
KBPersonaChatCell 布局
┌─────────────────────────────┐
│ 背景图(coverImageUrl) │
│ ┌─────────────────────┐ │
│ │ 半透明遮罩(黑色 0.3) │ │
│ │ │ │
│ │ ┌───┐ │ │
│ │ │头像│ │ │
│ │ └───┘ │ │
│ │ 人设名称 │ │
│ │ 简短描述 │ │
│ │ │ │
│ │ ┌───────────────┐ │ │
│ │ │ 聊天记录列表 │ │ │
│ │ │ (待实现) │ │ │
│ │ └───────────────┘ │ │
│ └─────────────────────┘ │
└─────────────────────────────┘
✅ 已完成功能
- ✅ Model 层:KBPersonaModel、KBPersonaPageModel
- ✅ VM 层:AiVM 新增人设列表接口
- ✅ View 层:KBPersonaChatCell(基础 UI)
- ✅ VC 层:KBAIHomeVC(分页加载、竖向翻页、预加载)
- ✅ MJExtension 配置:JSON 自动转 Model
- ✅ 懒加载:所有控件使用懒加载
- ✅ Masonry 布局:纯代码布局
🚧 待实现功能
1. 聊天记录展示
- 需要后端提供
chatId字段 - 用
chatId请求聊天记录接口 - 在
KBPersonaChatCell的tableView中展示聊天记录
2. 聊天功能
- 点击输入框发送消息
- 接收 AI 回复
- 支持语音消息
3. 错误处理
- 网络请求失败提示
- 空数据占位图
- 加载中状态
4. 性能优化
- Cell 高度缓存
- 图片缓存策略
- 内存管理(清理不可见 Cell 的数据)
📝 使用方式
1. 在其他 VC 中跳转
KBAIHomeVC *homeVC = [[KBAIHomeVC alloc] init];
[self.navigationController pushViewController:homeVC animated:YES];
2. 作为 TabBar 的一个页面
KBAIHomeVC *homeVC = [[KBAIHomeVC alloc] init];
homeVC.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"AI聊天"
image:[UIImage imageNamed:@"tab_ai"]
selectedImage:[UIImage imageNamed:@"tab_ai_sel"]];
🐛 调试日志
网络请求日志
[AiVM] /ai-companion/page request: {pageNum: 1, pageSize: 10}
[AiVM] /ai-companion/page response: {...}
加载成功:当前 10 条,总共 100 条,还有更多:是
预加载日志
预加载第 0 个人设
预加载第 1 个人设
预加载第 2 个人设
当前在第 1 个人设:温柔小姐姐
📌 注意事项
- 接口地址:需要在
KBAPI.h中定义/ai-companion/page - 图片占位图:需要添加
placeholder_bg和placeholder_avatar图片资源 - 线程安全:网络回调后需要回到主线程更新 UI
- 内存管理:注意使用
weakSelf避免循环引用 - 字段兼容:后端可能返回
null,已做容错处理
🎯 下一步计划
- 接入真实的聊天记录接口
- 实现聊天输入和发送功能
- 优化 Cell 的聊天记录展示(使用现有的 KBChatTableView)
- 添加下拉刷新和上拉加载更多
- 添加错误提示和空数据占位图