// // KBChatTestVC.m // keyBoard // // Created by Kiro on 2026/1/23. // #import "KBChatTestVC.h" #import "KBChatTableView.h" #import @interface KBChatTestVC () @property (nonatomic, strong) KBChatTableView *chatView; @property (nonatomic, strong) UIButton *addUserMessageButton; @property (nonatomic, strong) UIButton *addAIMessageButton; @property (nonatomic, strong) UIButton *clearButton; @end @implementation KBChatTestVC - (void)viewDidLoad { [super viewDidLoad]; self.title = @"聊天 UI 测试"; self.view.backgroundColor = [UIColor whiteColor]; [self setupUI]; [self loadMockData]; } - (void)setupUI { // 聊天视图 self.chatView = [[KBChatTableView alloc] init]; self.chatView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0]; [self.view addSubview:self.chatView]; // 按钮容器 UIView *buttonContainer = [[UIView alloc] init]; buttonContainer.backgroundColor = [UIColor whiteColor]; [self.view addSubview:buttonContainer]; // 添加用户消息按钮 self.addUserMessageButton = [UIButton buttonWithType:UIButtonTypeSystem]; [self.addUserMessageButton setTitle:@"添加用户消息" forState:UIControlStateNormal]; [self.addUserMessageButton addTarget:self action:@selector(addUserMessage) forControlEvents:UIControlEventTouchUpInside]; [buttonContainer addSubview:self.addUserMessageButton]; // 添加 AI 消息按钮 self.addAIMessageButton = [UIButton buttonWithType:UIButtonTypeSystem]; [self.addAIMessageButton setTitle:@"添加 AI 消息" forState:UIControlStateNormal]; [self.addAIMessageButton addTarget:self action:@selector(addAIMessage) forControlEvents:UIControlEventTouchUpInside]; [buttonContainer addSubview:self.addAIMessageButton]; // 清空按钮 self.clearButton = [UIButton buttonWithType:UIButtonTypeSystem]; [self.clearButton setTitle:@"清空" forState:UIControlStateNormal]; [self.clearButton addTarget:self action:@selector(clearMessages) forControlEvents:UIControlEventTouchUpInside]; [buttonContainer addSubview:self.clearButton]; // 布局 [self.chatView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop); make.left.right.equalTo(self.view); make.bottom.equalTo(buttonContainer.mas_top); }]; [buttonContainer mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self.view); make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom); make.height.mas_equalTo(60); }]; [self.addUserMessageButton mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(buttonContainer).offset(16); make.centerY.equalTo(buttonContainer); }]; [self.addAIMessageButton mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(buttonContainer); }]; [self.clearButton mas_makeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(buttonContainer).offset(-16); make.centerY.equalTo(buttonContainer); }]; } - (void)loadMockData { // 模拟对话数据 [self.chatView addUserMessage:@"你好"]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [self.chatView addAssistantMessage:@"你好!很高兴见到你。" audioDuration:3.0 audioData:[self generateMockAudioData:3.0]]; }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [self.chatView addUserMessage:@"今天天气怎么样?"]; }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [self.chatView addAssistantMessage:@"今天天气不错,阳光明媚,温度适宜,非常适合外出活动。" audioDuration:8.0 audioData:[self generateMockAudioData:8.0]]; }); } - (void)addUserMessage { static NSInteger userMessageCount = 0; userMessageCount++; NSString *text = [NSString stringWithFormat:@"这是用户消息 %ld", (long)userMessageCount]; [self.chatView addUserMessage:text]; } - (void)addAIMessage { static NSInteger aiMessageCount = 0; aiMessageCount++; NSString *text = [NSString stringWithFormat:@"这是 AI 回复消息 %ld,包含一些较长的文本内容,用于测试气泡的自适应高度和换行效果。", (long)aiMessageCount]; NSTimeInterval duration = 5.0 + (aiMessageCount % 10); [self.chatView addAssistantMessage:text audioDuration:duration audioData:[self generateMockAudioData:duration]]; } - (void)clearMessages { [self.chatView clearMessages]; } /// 生成模拟音频数据(实际项目中应该从 TTS 获取) - (NSData *)generateMockAudioData:(NSTimeInterval)duration { // 这里返回 nil,实际使用时应该传入真实的音频数据 // 为了测试,可以加载一个本地音频文件 NSString *audioPath = [[NSBundle mainBundle] pathForResource:@"ai_test" ofType:@"m4a"]; if (audioPath) { return [NSData dataWithContentsOfFile:audioPath]; } return nil; } @end