This commit is contained in:
2026-01-27 18:53:19 +08:00
parent b34de116a3
commit db869552e4
16 changed files with 402 additions and 3 deletions

View File

@@ -74,6 +74,13 @@ typedef NS_ENUM(NSInteger, KBPersonaVisibility) {
/// 更新时间
@property (nonatomic, copy) NSString *updatedAt;
/// 评论数
@property (nonatomic, copy) NSString *commentCount;
/// 喜欢数
@property (nonatomic, copy) NSString *likeCount;
/// 是否喜欢
@property (nonatomic, assign) BOOL liked;
#pragma mark - 扩展属性

View File

@@ -89,7 +89,8 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
make.edges.equalTo(self);
}];
self.contentBottomInset = KB_TABBAR_HEIGHT + 40 + 10;
// contentBottomInset chatView
self.contentBottomInset = 20; //
[self updateContentBottomInset:self.contentBottomInset];
__weak typeof(self) weakSelf = self;

View File

@@ -10,6 +10,7 @@
#import "KBAiChatMessage.h"
#import "KBChatHistoryPageModel.h"
#import "AiVM.h"
#import "KBImagePositionButton.h"
#import <Masonry/Masonry.h>
#import <SDWebImage/SDWebImage.h>
@@ -48,6 +49,12 @@
/// AiVM
@property (nonatomic, strong) AiVM *aiVM;
///
@property (nonatomic, strong) KBImagePositionButton *commentButton;
///
@property (nonatomic, strong) KBImagePositionButton *likeButton;
@end
@implementation KBPersonaChatCell
@@ -113,6 +120,24 @@
make.centerY.equalTo(self.avatarImageView);
}];
//
[self.contentView addSubview:self.commentButton];
[self.commentButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.contentView).offset(-20);
make.centerY.equalTo(self.avatarImageView);
make.width.mas_equalTo(40);
make.height.mas_equalTo(50);
}];
// 20px
[self.contentView addSubview:self.likeButton];
[self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.commentButton.mas_left).offset(-20);
make.centerY.equalTo(self.avatarImageView);
make.width.mas_equalTo(40);
make.height.mas_equalTo(50);
}];
//
[self.contentView addSubview:self.chatView];
[self.chatView mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -147,6 +172,10 @@
//
[self.chatView stopPlayingAudio];
[self.chatView clearMessages];
[self.commentButton setTitle:persona.commentCount forState:UIControlStateNormal];
[self.likeButton setTitle:persona.likeCount forState:UIControlStateNormal];
self.likeButton.selected = persona.liked;
}
#pragma mark - 2
@@ -350,7 +379,7 @@
- (UILabel *)nameLabel {
if (!_nameLabel) {
_nameLabel = [[UILabel alloc] init];
_nameLabel.font = [UIFont boldSystemFontOfSize:20];
_nameLabel.font = [UIFont boldSystemFontOfSize:12];
_nameLabel.textColor = [UIColor whiteColor];
_nameLabel.textAlignment = NSTextAlignmentCenter;
}
@@ -377,4 +406,63 @@
return _chatView;
}
- (KBImagePositionButton *)commentButton {
if (!_commentButton) {
//
_commentButton = [[KBImagePositionButton alloc] initWithImagePosition:KBImagePositionTop spacing:4];
//
_commentButton.titleLabel.font = [UIFont systemFontOfSize:10];
//
[_commentButton setImage:[UIImage imageNamed:@"ai_comment_icon"] forState:UIControlStateNormal];
//
[_commentButton setTitle:@"0" forState:UIControlStateNormal];
[_commentButton setTitleColor:[[UIColor whiteColor] colorWithAlphaComponent:0.8] forState:UIControlStateNormal];
//
[_commentButton addTarget:self action:@selector(commentButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
return _commentButton;
}
- (KBImagePositionButton *)likeButton {
if (!_likeButton) {
//
_likeButton = [[KBImagePositionButton alloc] initWithImagePosition:KBImagePositionTop spacing:4];
//
_likeButton.titleLabel.font = [UIFont systemFontOfSize:10];
//
[_likeButton setImage:[UIImage imageNamed:@"ai_live_icon"] forState:UIControlStateNormal];
[_likeButton setImage:[UIImage imageNamed:@"ai_livesel_icon"] forState:UIControlStateSelected];
//
[_likeButton setTitle:@"0" forState:UIControlStateNormal];
[_likeButton setTitleColor:[[UIColor whiteColor] colorWithAlphaComponent:0.8] forState:UIControlStateNormal];
//
[_likeButton addTarget:self action:@selector(likeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
}
return _likeButton;
}
#pragma mark - Button Actions
- (void)commentButtonTapped:(KBImagePositionButton *)sender {
sender.selected = !sender.selected;
NSLog(@"[KBPersonaChatCell] 评论按钮点击,选中状态:%d", sender.selected);
// TODO:
}
- (void)likeButtonTapped:(KBImagePositionButton *)sender {
sender.selected = !sender.selected;
NSLog(@"[KBPersonaChatCell] 喜欢按钮点击,选中状态:%d", sender.selected);
// TODO:
}
@end

View File

@@ -422,7 +422,12 @@
- (void)updateChatViewBottomInset {
CGFloat bottomSpacing = (self.currentKeyboardHeight > 0.0) ? (self.currentKeyboardHeight + 8.0) : self.baseInputBarBottomSpacing;
CGFloat bottomInset = self.voiceInputBarHeight + bottomSpacing;
// bottomInset chatView avatar
// 20 chatView
CGFloat bottomInset = 20; //
NSLog(@"[KBAIHomeVC] 更新 ChatView bottomInset: %.2f", bottomInset);
for (NSIndexPath *indexPath in self.collectionView.indexPathsForVisibleItems) {
KBPersonaChatCell *cell = (KBPersonaChatCell *)[self.collectionView cellForItemAtIndexPath:indexPath];

View File

@@ -0,0 +1,39 @@
//
// KBImagePositionButton.h
// keyBoard
//
// Created by Kiro on 2026/1/27.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
/// 图片位置枚举
typedef NS_ENUM(NSInteger, KBImagePosition) {
KBImagePositionTop, // 图片在上,文字在下
KBImagePositionBottom, // 图片在下,文字在上
KBImagePositionLeft, // 图片在左,文字在右(默认)
KBImagePositionRight // 图片在右,文字在左
};
/// 可以指定图片位置的按钮
@interface KBImagePositionButton : UIButton
/// 图片位置(默认 KBImagePositionLeft
@property (nonatomic, assign) KBImagePosition imagePosition;
/// 图片和文字之间的间距(默认 8
@property (nonatomic, assign) CGFloat spacing;
/**
便捷初始化方法
@param imagePosition 图片位置
@param spacing 图片和文字之间的间距
*/
- (instancetype)initWithImagePosition:(KBImagePosition)imagePosition spacing:(CGFloat)spacing;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,187 @@
//
// KBImagePositionButton.m
// keyBoard
//
// Created by Kiro on 2026/1/27.
//
#import "KBImagePositionButton.h"
@implementation KBImagePositionButton
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
[self setupDefault];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder {
if (self = [super initWithCoder:coder]) {
[self setupDefault];
}
return self;
}
- (instancetype)initWithImagePosition:(KBImagePosition)imagePosition spacing:(CGFloat)spacing {
if (self = [super initWithFrame:CGRectZero]) {
_imagePosition = imagePosition;
_spacing = spacing;
[self setupDefault];
}
return self;
}
- (void)setupDefault {
// _imagePosition == 0 KBImagePositionTop 0
// initWithFrame initWithCoder _imagePosition 0 (KBImagePositionTop)
// initWithImagePosition _imagePosition
//
if (self.spacing == 0) {
_spacing = 8;
}
[self updateEdgeInsets];
}
#pragma mark - Setter
- (void)setImagePosition:(KBImagePosition)imagePosition {
_imagePosition = imagePosition;
[self updateEdgeInsets];
[self setNeedsLayout];
}
- (void)setSpacing:(CGFloat)spacing {
_spacing = spacing;
[self updateEdgeInsets];
[self setNeedsLayout];
}
- (void)setImage:(UIImage *)image forState:(UIControlState)state {
[super setImage:image forState:state];
// image
dispatch_async(dispatch_get_main_queue(), ^{
[self updateEdgeInsets];
});
}
- (void)setTitle:(NSString *)title forState:(UIControlState)state {
[super setTitle:title forState:state];
// title
dispatch_async(dispatch_get_main_queue(), ^{
[self updateEdgeInsets];
});
}
#pragma mark - EdgeInsets
- (void)updateEdgeInsets {
CGSize imageSize = self.currentImage.size;
CGSize titleSize = CGSizeZero;
if (self.currentTitle.length > 0 && self.titleLabel.font) {
NSDictionary *attributes = @{NSFontAttributeName: self.titleLabel.font};
titleSize = [self.currentTitle sizeWithAttributes:attributes];
}
switch (self.imagePosition) {
case KBImagePositionTop: {
//
self.imageEdgeInsets = UIEdgeInsetsMake(
-(titleSize.height + self.spacing), // top:
0, // left
0, // bottom
-titleSize.width // right:
);
self.titleEdgeInsets = UIEdgeInsetsMake(
imageSize.height + self.spacing, // top:
-imageSize.width, // left:
0, // bottom
0 // right
);
break;
}
case KBImagePositionBottom: {
//
self.imageEdgeInsets = UIEdgeInsetsMake(
titleSize.height + self.spacing, // top:
0, // left
0, // bottom
-titleSize.width // right
);
self.titleEdgeInsets = UIEdgeInsetsMake(
-(imageSize.height + self.spacing), // top:
-imageSize.width, // left
0, // bottom
0 // right
);
break;
}
case KBImagePositionLeft: {
//
self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, self.spacing);
self.titleEdgeInsets = UIEdgeInsetsMake(0, self.spacing, 0, 0);
break;
}
case KBImagePositionRight: {
//
self.imageEdgeInsets = UIEdgeInsetsMake(
0,
titleSize.width + self.spacing,
0,
-(titleSize.width + self.spacing)
);
self.titleEdgeInsets = UIEdgeInsetsMake(
0,
-(imageSize.width + self.spacing),
0,
imageSize.width + self.spacing
);
break;
}
}
NSLog(@"imageEdgeInsets: %@", NSStringFromUIEdgeInsets(self.imageEdgeInsets));
NSLog(@"titleEdgeInsets: %@", NSStringFromUIEdgeInsets(self.titleEdgeInsets));
}
- (CGSize)intrinsicContentSize {
CGSize imageSize = self.currentImage ? self.currentImage.size : CGSizeZero;
CGSize titleSize = CGSizeZero;
if (self.currentTitle.length > 0 && self.titleLabel.font) {
NSDictionary *attributes = @{NSFontAttributeName: self.titleLabel.font};
titleSize = [self.currentTitle sizeWithAttributes:attributes];
}
CGSize size = CGSizeZero;
switch (self.imagePosition) {
case KBImagePositionTop:
case KBImagePositionBottom: {
//
size.width = MAX(imageSize.width, titleSize.width);
size.height = imageSize.height + self.spacing + titleSize.height;
break;
}
case KBImagePositionLeft:
case KBImagePositionRight: {
//
size.width = imageSize.width + self.spacing + titleSize.width;
size.height = MAX(imageSize.height, titleSize.height);
break;
}
}
return size;
}
@end