// // KBChatUserMessageCell.m // keyBoard // // Created by Kiro on 2026/1/23. // #import "KBChatUserMessageCell.h" #import "KBAiChatMessage.h" #import @interface KBChatUserMessageCell () @property (nonatomic, strong) UIView *bubbleView; @property (nonatomic, strong) UILabel *messageLabel; @property (nonatomic, strong) UIActivityIndicatorView *loadingIndicator; @end @implementation KBChatUserMessageCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { self.backgroundColor = [UIColor clearColor]; self.selectionStyle = UITableViewCellSelectionStyleNone; [self setupUI]; } return self; } - (void)setupUI { // 气泡视图 self.bubbleView = [[UIView alloc] init]; self.bubbleView.backgroundColor = [UIColor colorWithRed:0.94 green:0.94 blue:0.94 alpha:1.0]; self.bubbleView.layer.cornerRadius = 16; self.bubbleView.layer.masksToBounds = YES; [self.contentView addSubview:self.bubbleView]; // 消息标签 self.messageLabel = [[UILabel alloc] init]; self.messageLabel.numberOfLines = 0; self.messageLabel.font = [UIFont systemFontOfSize:16]; self.messageLabel.textColor = [UIColor blackColor]; self.messageLabel.textAlignment = NSTextAlignmentLeft; [self.bubbleView addSubview:self.messageLabel]; // 加载指示器 self.loadingIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; self.loadingIndicator.hidesWhenStopped = YES; [self.contentView addSubview:self.loadingIndicator]; // 布局约束 [self.bubbleView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.contentView).offset(4); make.bottom.equalTo(self.contentView).offset(-4); make.right.equalTo(self.contentView).offset(-16); make.width.lessThanOrEqualTo(self.contentView).multipliedBy(0.75); // 最小高度约束,确保 loading 时气泡不消失 make.height.greaterThanOrEqualTo(@40); make.width.greaterThanOrEqualTo(@50); }]; [self.messageLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.bubbleView).offset(10); make.bottom.equalTo(self.bubbleView).offset(-10); make.left.equalTo(self.bubbleView).offset(12); make.right.equalTo(self.bubbleView).offset(-12); }]; [self.loadingIndicator mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.equalTo(self.contentView); make.right.equalTo(self.contentView).offset(-16); }]; } - (void)configureWithMessage:(KBAiChatMessage *)message { self.messageLabel.text = message.text; [self updateMessageAlignmentForText:message.text]; if (message.isLoading) { self.bubbleView.hidden = YES; [self.loadingIndicator startAnimating]; } else { self.bubbleView.hidden = NO; self.messageLabel.hidden = NO; [self.loadingIndicator stopAnimating]; } } - (void)updateMessageAlignmentForText:(NSString *)text { if (self.messageLabel.hidden || text.length == 0) { return; } if ([text rangeOfString:@"\n"].location != NSNotFound) { self.messageLabel.textAlignment = NSTextAlignmentLeft; return; } CGSize singleLineSize = [text sizeWithAttributes:@{NSFontAttributeName: self.messageLabel.font}]; CGFloat minBubbleWidth = 50.0; CGFloat padding = 24.0; if (singleLineSize.width + padding <= minBubbleWidth + 0.5) { self.messageLabel.textAlignment = NSTextAlignmentCenter; } else { self.messageLabel.textAlignment = NSTextAlignmentLeft; } } @end