From 3dfb8f31e212f2bd3dc52a4ab38a795991d550d7 Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Fri, 16 Jan 2026 19:09:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E5=A5=BD=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- keyBoard/Class/AiTalk/M/KBAICommentModel.h | 19 +- keyBoard/Class/AiTalk/M/KBAICommentModel.m | 60 +++-- keyBoard/Class/AiTalk/M/KBAIReplyModel.h | 9 + keyBoard/Class/AiTalk/M/KBAIReplyModel.m | 38 +++ keyBoard/Class/AiTalk/M/comments_mock.json | 220 +++++---------- .../Class/AiTalk/V/KBAICommentFooterView.m | 10 - .../Class/AiTalk/V/KBAICommentHeaderView.m | 2 +- keyBoard/Class/AiTalk/V/KBAICommentView.m | 252 ++++-------------- keyBoard/Class/AiTalk/V/KBAIReplyCell.m | 3 +- 9 files changed, 211 insertions(+), 402 deletions(-) diff --git a/keyBoard/Class/AiTalk/M/KBAICommentModel.h b/keyBoard/Class/AiTalk/M/KBAICommentModel.h index 1a15a92..5b9ed5e 100644 --- a/keyBoard/Class/AiTalk/M/KBAICommentModel.h +++ b/keyBoard/Class/AiTalk/M/KBAICommentModel.h @@ -14,9 +14,8 @@ NS_ASSUME_NONNULL_BEGIN /// Footer 状态枚举 typedef NS_ENUM(NSInteger, KBAIReplyFooterState) { KBAIReplyFooterStateHidden, // 无二级评论,不显示 - KBAIReplyFooterStateExpand, // 显示"展开x条回复"(初始折叠状态) - KBAIReplyFooterStateLoadMore, // 显示"加载更多"(已展开部分) - KBAIReplyFooterStateCollapse // 显示"收起"(全部展开后) + KBAIReplyFooterStateExpand, // 显示"展开x条回复"(折叠状态) + KBAIReplyFooterStateCollapse // 显示"收起"(展开状态) }; /// 一级评论模型 @@ -63,6 +62,11 @@ typedef NS_ENUM(NSInteger, KBAIReplyFooterState) { /// 回复是否已展开 @property(nonatomic, assign) BOOL isRepliesExpanded; +#pragma mark - 缓存高度 + +/// Header 高度缓存 +@property(nonatomic, assign) CGFloat cachedHeaderHeight; + #pragma mark - Helper Methods /// 格式化后的时间字符串 @@ -71,13 +75,16 @@ typedef NS_ENUM(NSInteger, KBAIReplyFooterState) { /// 获取当前 Footer 状态 - (KBAIReplyFooterState)footerState; -/// 展开更多回复(每次加载指定数量) -/// @param count 本次加载的数量 -- (void)loadMoreReplies:(NSInteger)count; +/// 展开全部回复 +- (void)expandAllReplies; /// 收起所有回复 - (void)collapseReplies; +/// 计算 Header 高度 +/// @param maxWidth 最大宽度 +- (CGFloat)calculateHeaderHeightWithMaxWidth:(CGFloat)maxWidth; + @end NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/AiTalk/M/KBAICommentModel.m b/keyBoard/Class/AiTalk/M/KBAICommentModel.m index 40580f1..5346cc1 100644 --- a/keyBoard/Class/AiTalk/M/KBAICommentModel.m +++ b/keyBoard/Class/AiTalk/M/KBAICommentModel.m @@ -64,37 +64,55 @@ return KBAIReplyFooterStateHidden; } - // 未展开(初始状态) - if (!self.isRepliesExpanded) { - return KBAIReplyFooterStateExpand; + // 已展开 + if (self.isRepliesExpanded) { + return KBAIReplyFooterStateCollapse; } - // 已展开但还有更多 - if (self.displayedReplies.count < self.totalReplyCount) { - return KBAIReplyFooterStateLoadMore; - } - - // 全部展开,显示收起 - return KBAIReplyFooterStateCollapse; + // 未展开 + return KBAIReplyFooterStateExpand; } -- (void)loadMoreReplies:(NSInteger)count { +- (void)expandAllReplies { self.isRepliesExpanded = YES; - - NSInteger currentCount = self.displayedReplies.count; - NSInteger endIndex = MIN(currentCount + count, self.replies.count); - - for (NSInteger i = currentCount; i < endIndex; i++) { - [self.displayedReplies addObject:self.replies[i]]; - } - - self.hasMoreReplies = (self.displayedReplies.count < self.totalReplyCount); + [self.displayedReplies removeAllObjects]; + [self.displayedReplies addObjectsFromArray:self.replies]; } - (void)collapseReplies { self.isRepliesExpanded = NO; [self.displayedReplies removeAllObjects]; - self.hasMoreReplies = self.totalReplyCount > 0; +} + +- (CGFloat)calculateHeaderHeightWithMaxWidth:(CGFloat)maxWidth { + if (self.cachedHeaderHeight > 0) { + return self.cachedHeaderHeight; + } + + // Header 布局: + // 头像(40) + 间距(12) + 内容区域 + 间距(50,点赞按钮) + 右边距(16) + // 内容区域宽度 = maxWidth - 16(左边距) - 40(头像) - 12(间距) - 50(点赞) - 16(右边距) + CGFloat contentWidth = maxWidth - 16 - 40 - 12 - 50 - 16; + + // 用户名高度(单行) + CGFloat userNameHeight = 17; // 14号字体 + + // 时间高度(单行) + CGFloat timeHeight = 15; // 12号字体 + + // 内容高度(多行) + UIFont *contentFont = [UIFont systemFontOfSize:15]; + CGRect contentRect = [self.content boundingRectWithSize:CGSizeMake(contentWidth, CGFLOAT_MAX) + options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading + attributes:@{NSFontAttributeName: contentFont} + context:nil]; + CGFloat contentHeight = ceil(contentRect.size.height); + + // 总高度 = 上边距(12) + 用户名 + 间距(2) + 时间 + 间距(8) + 内容 + 下边距(12) + CGFloat totalHeight = 12 + userNameHeight + 2 + timeHeight + 8 + contentHeight + 12; + + self.cachedHeaderHeight = totalHeight; + return totalHeight; } @end diff --git a/keyBoard/Class/AiTalk/M/KBAIReplyModel.h b/keyBoard/Class/AiTalk/M/KBAIReplyModel.h index 0c86f12..e28328b 100644 --- a/keyBoard/Class/AiTalk/M/KBAIReplyModel.h +++ b/keyBoard/Class/AiTalk/M/KBAIReplyModel.h @@ -39,9 +39,18 @@ NS_ASSUME_NONNULL_BEGIN /// 创建时间(时间戳) @property(nonatomic, assign) NSTimeInterval createTime; +#pragma mark - 缓存高度 + +/// Cell 高度缓存 +@property(nonatomic, assign) CGFloat cachedCellHeight; + /// 格式化后的时间字符串 - (NSString *)formattedTime; +/// 计算 Cell 高度 +/// @param maxWidth 最大宽度 +- (CGFloat)calculateCellHeightWithMaxWidth:(CGFloat)maxWidth; + @end NS_ASSUME_NONNULL_END diff --git a/keyBoard/Class/AiTalk/M/KBAIReplyModel.m b/keyBoard/Class/AiTalk/M/KBAIReplyModel.m index 25093a7..d63bfb8 100644 --- a/keyBoard/Class/AiTalk/M/KBAIReplyModel.m +++ b/keyBoard/Class/AiTalk/M/KBAIReplyModel.m @@ -37,4 +37,42 @@ } } +- (CGFloat)calculateCellHeightWithMaxWidth:(CGFloat)maxWidth { + if (self.cachedCellHeight > 0) { + return self.cachedCellHeight; + } + + // Cell 布局: + // 左边距(68) + 头像(28) + 间距(8) + 内容区域 + 间距(8) + 点赞按钮(40) + 右边距(16) + // 内容区域宽度 = maxWidth - 68 - 28 - 8 - 8 - 40 - 16 + CGFloat contentWidth = maxWidth - 68 - 28 - 8 - 8 - 40 - 16; + + // 构建富文本计算高度 + NSMutableString *fullText = [NSMutableString stringWithString:self.userName]; + if (self.replyToUserName.length > 0) { + [fullText appendFormat:@" 回复 @%@", self.replyToUserName]; + } + [fullText appendFormat:@":%@", self.content]; + + UIFont *contentFont = [UIFont systemFontOfSize:14]; + CGRect contentRect = [fullText boundingRectWithSize:CGSizeMake(contentWidth, CGFLOAT_MAX) + options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading + attributes:@{NSFontAttributeName: contentFont} + context:nil]; + CGFloat contentHeight = ceil(contentRect.size.height); + + // 时间高度(单行) + CGFloat timeHeight = 14; // 11号字体 + + // 总高度 = 上边距(8) + 内容 + 间距(4) + 时间 + 下边距(8) + CGFloat totalHeight = 8 + contentHeight + 4 + timeHeight + 8; + + // 最小高度(头像高度 + 上下边距) + CGFloat minHeight = 8 + 28 + 8; + totalHeight = MAX(totalHeight, minHeight); + + self.cachedCellHeight = totalHeight; + return totalHeight; +} + @end diff --git a/keyBoard/Class/AiTalk/M/comments_mock.json b/keyBoard/Class/AiTalk/M/comments_mock.json index 5ea2aaf..1c73f6e 100644 --- a/keyBoard/Class/AiTalk/M/comments_mock.json +++ b/keyBoard/Class/AiTalk/M/comments_mock.json @@ -1,5 +1,5 @@ { - "totalCount": 1258, + "totalCount": 5628, "comments": [ { "id": "comment_001", @@ -11,77 +11,11 @@ "isLiked": false, "createTime": 1737010800, "replies": [ - { - "id": "reply_001_1", - "userId": "user_102", - "userName": "科技达人", - "avatarUrl": "https://picsum.photos/100/100?random=2", - "content": "同意!这个设计真的很用心", - "likeCount": 45, - "isLiked": false, - "createTime": 1737014400 - }, - { - "id": "reply_001_2", - "userId": "user_103", - "userName": "程序员小李", - "avatarUrl": "https://picsum.photos/100/100?random=3", - "content": "感谢支持,会继续努力的!", - "replyToUserName": "科技达人", - "likeCount": 23, - "isLiked": true, - "createTime": 1737018000 - }, - { - "id": "reply_001_3", - "userId": "user_104", - "userName": "产品经理", - "avatarUrl": "https://picsum.photos/100/100?random=4", - "content": "下个版本会有更多惊喜", - "likeCount": 12, - "isLiked": false, - "createTime": 1737021600 - }, - { - "id": "reply_001_4", - "userId": "user_105", - "userName": "UI设计师", - "avatarUrl": "https://picsum.photos/100/100?random=5", - "content": "细节决定品质", - "likeCount": 8, - "isLiked": false, - "createTime": 1737025200 - }, - { - "id": "reply_001_5", - "userId": "user_106", - "userName": "测试工程师", - "avatarUrl": "https://picsum.photos/100/100?random=6", - "content": "已经测试通过了,稳定性很好", - "likeCount": 5, - "isLiked": false, - "createTime": 1737028800 - }, - { - "id": "reply_001_6", - "userId": "user_107", - "userName": "运营妹子", - "avatarUrl": "https://picsum.photos/100/100?random=7", - "content": "用户反馈都很正面", - "likeCount": 3, - "isLiked": false, - "createTime": 1737032400 - }, - { - "id": "reply_001_7", - "userId": "user_108", - "userName": "后端大神", - "avatarUrl": "https://picsum.photos/100/100?random=8", - "content": "接口性能优化了30%", - "likeCount": 15, - "isLiked": false, - "createTime": 1737036000 - } + {"id": "reply_001_1", "userId": "user_102", "userName": "科技达人", "avatarUrl": "https://picsum.photos/100/100?random=2", "content": "同意!这个设计真的很用心", "likeCount": 45, "isLiked": false, "createTime": 1737014400}, + {"id": "reply_001_2", "userId": "user_103", "userName": "程序员小李", "avatarUrl": "https://picsum.photos/100/100?random=3", "content": "感谢支持,会继续努力的!", "replyToUserName": "科技达人", "likeCount": 23, "isLiked": true, "createTime": 1737018000}, + {"id": "reply_001_3", "userId": "user_104", "userName": "产品经理", "avatarUrl": "https://picsum.photos/100/100?random=4", "content": "下个版本会有更多惊喜", "likeCount": 12, "isLiked": false, "createTime": 1737021600}, + {"id": "reply_001_4", "userId": "user_105", "userName": "UI设计师", "avatarUrl": "https://picsum.photos/100/100?random=5", "content": "细节决定品质", "likeCount": 8, "isLiked": false, "createTime": 1737025200}, + {"id": "reply_001_5", "userId": "user_106", "userName": "测试工程师", "avatarUrl": "https://picsum.photos/100/100?random=6", "content": "已经测试通过了,稳定性很好", "likeCount": 5, "isLiked": false, "createTime": 1737028800} ] }, { @@ -94,60 +28,22 @@ "isLiked": false, "createTime": 1736924400, "replies": [ - { - "id": "reply_002_1", - "userId": "user_202", - "userName": "官方客服", - "avatarUrl": "https://picsum.photos/100/100?random=11", - "content": "目前支持中文、英文,日语输入法正在开发中,预计下月上线", - "likeCount": 32, - "isLiked": false, - "createTime": 1736928000 - }, - { - "id": "reply_002_2", - "userId": "user_201", - "userName": "热心网友", - "avatarUrl": "https://picsum.photos/100/100?random=10", - "content": "太好了,期待!", - "replyToUserName": "官方客服", - "likeCount": 5, - "isLiked": false, - "createTime": 1736931600 - } + {"id": "reply_002_1", "userId": "user_202", "userName": "官方客服", "avatarUrl": "https://picsum.photos/100/100?random=11", "content": "目前支持中文、英文,日语输入法正在开发中", "likeCount": 32, "isLiked": false, "createTime": 1736928000}, + {"id": "reply_002_2", "userId": "user_201", "userName": "热心网友", "avatarUrl": "https://picsum.photos/100/100?random=10", "content": "太好了,期待!", "replyToUserName": "官方客服", "likeCount": 5, "isLiked": false, "createTime": 1736931600} ] }, - { - "id": "comment_003", - "userId": "user_301", - "userName": "设计爱好者", - "avatarUrl": "https://picsum.photos/100/100?random=12", - "content": "这个UI设计太精美了,配色方案很舒服,是哪位设计师的作品?", - "likeCount": 256, - "isLiked": true, - "createTime": 1736838000, - "replies": [] - }, + {"id": "comment_003", "userId": "user_301", "userName": "设计爱好者", "avatarUrl": "https://picsum.photos/100/100?random=12", "content": "这个UI设计太精美了,配色方案很舒服", "likeCount": 256, "isLiked": true, "createTime": 1736838000, "replies": []}, { "id": "comment_004", "userId": "user_401", "userName": "效率达人", "avatarUrl": "https://picsum.photos/100/100?random=13", - "content": "自从用了这个键盘,打字速度提升了一倍!强烈推荐给大家", + "content": "自从用了这个键盘,打字速度提升了一倍!强烈推荐", "likeCount": 512, "isLiked": false, "createTime": 1736751600, "replies": [ - { - "id": "reply_004_1", - "userId": "user_402", - "userName": "新用户", - "avatarUrl": "https://picsum.photos/100/100?random=14", - "content": "真的吗?那我也要试试", - "likeCount": 18, - "isLiked": false, - "createTime": 1736755200 - } + {"id": "reply_004_1", "userId": "user_402", "userName": "新用户", "avatarUrl": "https://picsum.photos/100/100?random=14", "content": "真的吗?那我也要试试", "likeCount": 18, "isLiked": false, "createTime": 1736755200} ] }, { @@ -160,48 +56,60 @@ "isLiked": false, "createTime": 1736665200, "replies": [ - { - "id": "reply_005_1", - "userId": "user_502", - "userName": "粉丝A", - "avatarUrl": "https://picsum.photos/100/100?random=16", - "content": "博主的评测视频太专业了", - "likeCount": 56, - "isLiked": false, - "createTime": 1736668800 - }, - { - "id": "reply_005_2", - "userId": "user_503", - "userName": "粉丝B", - "avatarUrl": "https://picsum.photos/100/100?random=17", - "content": "已经去看了,确实很详细", - "likeCount": 23, - "isLiked": false, - "createTime": 1736672400 - }, - { - "id": "reply_005_3", - "userId": "user_504", - "userName": "路人甲", - "avatarUrl": "https://picsum.photos/100/100?random=18", - "content": "求链接", - "likeCount": 8, - "isLiked": false, - "createTime": 1736676000 - } + {"id": "reply_005_1", "userId": "user_502", "userName": "粉丝A", "avatarUrl": "https://picsum.photos/100/100?random=16", "content": "博主的评测视频太专业了", "likeCount": 56, "isLiked": false, "createTime": 1736668800}, + {"id": "reply_005_2", "userId": "user_503", "userName": "粉丝B", "avatarUrl": "https://picsum.photos/100/100?random=17", "content": "已经去看了,确实很详细", "likeCount": 23, "isLiked": false, "createTime": 1736672400}, + {"id": "reply_005_3", "userId": "user_504", "userName": "路人甲", "avatarUrl": "https://picsum.photos/100/100?random=18", "content": "求链接", "likeCount": 8, "isLiked": false, "createTime": 1736676000} ] }, - { - "id": "comment_006", - "userId": "user_601", - "userName": "老用户", - "avatarUrl": "https://picsum.photos/100/100?random=19", - "content": "用了三年了,一直很稳定,希望能出个暗黑主题", - "likeCount": 178, - "isLiked": false, - "createTime": 1736578800, - "replies": [] - } + {"id": "comment_006", "userId": "user_601", "userName": "老用户", "avatarUrl": "https://picsum.photos/100/100?random=19", "content": "用了三年了,一直很稳定,希望能出个暗黑主题", "likeCount": 178, "isLiked": false, "createTime": 1736578800, "replies": []}, + {"id": "comment_007", "userId": "user_701", "userName": "学生党", "avatarUrl": "https://picsum.photos/100/100?random=20", "content": "上课记笔记超方便的!", "likeCount": 67, "isLiked": false, "createTime": 1736492400, "replies": [{"id": "reply_007_1", "userId": "user_702", "userName": "同学", "avatarUrl": "https://picsum.photos/100/100?random=21", "content": "同感!", "likeCount": 3, "isLiked": false, "createTime": 1736496000}]}, + {"id": "comment_008", "userId": "user_801", "userName": "职场人", "avatarUrl": "https://picsum.photos/100/100?random=22", "content": "工作效率提升神器", "likeCount": 234, "isLiked": true, "createTime": 1736406000, "replies": []}, + {"id": "comment_009", "userId": "user_901", "userName": "游戏玩家", "avatarUrl": "https://picsum.photos/100/100?random=23", "content": "打游戏聊天也很顺手", "likeCount": 89, "isLiked": false, "createTime": 1736319600, "replies": [{"id": "reply_009_1", "userId": "user_902", "userName": "队友", "avatarUrl": "https://picsum.photos/100/100?random=24", "content": "确实,反应很快", "likeCount": 12, "isLiked": false, "createTime": 1736323200}]}, + {"id": "comment_010", "userId": "user_1001", "userName": "文字工作者", "avatarUrl": "https://picsum.photos/100/100?random=25", "content": "写文章必备工具", "likeCount": 156, "isLiked": false, "createTime": 1736233200, "replies": []}, + {"id": "comment_011", "userId": "user_1101", "userName": "程序员", "avatarUrl": "https://picsum.photos/100/100?random=26", "content": "代码补全功能太强了", "likeCount": 445, "isLiked": true, "createTime": 1736146800, "replies": [{"id": "reply_011_1", "userId": "user_1102", "userName": "后端开发", "avatarUrl": "https://picsum.photos/100/100?random=27", "content": "支持多少种语言?", "likeCount": 8, "isLiked": false, "createTime": 1736150400}, {"id": "reply_011_2", "userId": "user_1101", "userName": "程序员", "avatarUrl": "https://picsum.photos/100/100?random=26", "content": "主流语言都支持", "replyToUserName": "后端开发", "likeCount": 15, "isLiked": false, "createTime": 1736154000}]}, + {"id": "comment_012", "userId": "user_1201", "userName": "产品体验官", "avatarUrl": "https://picsum.photos/100/100?random=28", "content": "交互体验非常流畅", "likeCount": 78, "isLiked": false, "createTime": 1736060400, "replies": []}, + {"id": "comment_013", "userId": "user_1301", "userName": "手机发烧友", "avatarUrl": "https://picsum.photos/100/100?random=29", "content": "内存占用很小,不卡顿", "likeCount": 234, "isLiked": false, "createTime": 1735974000, "replies": [{"id": "reply_013_1", "userId": "user_1302", "userName": "技术控", "avatarUrl": "https://picsum.photos/100/100?random=30", "content": "优化做得真好", "likeCount": 23, "isLiked": false, "createTime": 1735977600}]}, + {"id": "comment_014", "userId": "user_1401", "userName": "颜值党", "avatarUrl": "https://picsum.photos/100/100?random=31", "content": "主题皮肤太好看了", "likeCount": 567, "isLiked": true, "createTime": 1735887600, "replies": []}, + {"id": "comment_015", "userId": "user_1501", "userName": "实用主义者", "avatarUrl": "https://picsum.photos/100/100?random=32", "content": "功能齐全,没有广告", "likeCount": 890, "isLiked": false, "createTime": 1735801200, "replies": [{"id": "reply_015_1", "userId": "user_1502", "userName": "同意", "avatarUrl": "https://picsum.photos/100/100?random=33", "content": "这点太重要了", "likeCount": 45, "isLiked": false, "createTime": 1735804800}]}, + {"id": "comment_016", "userId": "user_1601", "userName": "安全意识者", "avatarUrl": "https://picsum.photos/100/100?random=34", "content": "隐私保护做得很好", "likeCount": 345, "isLiked": false, "createTime": 1735714800, "replies": []}, + {"id": "comment_017", "userId": "user_1701", "userName": "多语言用户", "avatarUrl": "https://picsum.photos/100/100?random=35", "content": "中英文切换很方便", "likeCount": 123, "isLiked": false, "createTime": 1735628400, "replies": [{"id": "reply_017_1", "userId": "user_1702", "userName": "留学生", "avatarUrl": "https://picsum.photos/100/100?random=36", "content": "对我来说太实用了", "likeCount": 8, "isLiked": false, "createTime": 1735632000}]}, + {"id": "comment_018", "userId": "user_1801", "userName": "表情包达人", "avatarUrl": "https://picsum.photos/100/100?random=37", "content": "表情搜索功能爱了", "likeCount": 456, "isLiked": true, "createTime": 1735542000, "replies": []}, + {"id": "comment_019", "userId": "user_1901", "userName": "极简主义", "avatarUrl": "https://picsum.photos/100/100?random=38", "content": "界面简洁不花哨", "likeCount": 234, "isLiked": false, "createTime": 1735455600, "replies": []}, + {"id": "comment_020", "userId": "user_2001", "userName": "细节控", "avatarUrl": "https://picsum.photos/100/100?random=39", "content": "按键反馈手感很好", "likeCount": 178, "isLiked": false, "createTime": 1735369200, "replies": [{"id": "reply_020_1", "userId": "user_2002", "userName": "同感", "avatarUrl": "https://picsum.photos/100/100?random=40", "content": "震动反馈调得刚刚好", "likeCount": 12, "isLiked": false, "createTime": 1735372800}]}, + {"id": "comment_021", "userId": "user_2101", "userName": "夜猫子", "avatarUrl": "https://picsum.photos/100/100?random=41", "content": "夜间模式护眼", "likeCount": 89, "isLiked": false, "createTime": 1735282800, "replies": []}, + {"id": "comment_022", "userId": "user_2201", "userName": "速度党", "avatarUrl": "https://picsum.photos/100/100?random=42", "content": "滑动输入太爽了", "likeCount": 567, "isLiked": true, "createTime": 1735196400, "replies": [{"id": "reply_022_1", "userId": "user_2202", "userName": "新手", "avatarUrl": "https://picsum.photos/100/100?random=43", "content": "怎么开启?", "likeCount": 3, "isLiked": false, "createTime": 1735200000}, {"id": "reply_022_2", "userId": "user_2201", "userName": "速度党", "avatarUrl": "https://picsum.photos/100/100?random=42", "content": "设置里有", "replyToUserName": "新手", "likeCount": 5, "isLiked": false, "createTime": 1735203600}]}, + {"id": "comment_023", "userId": "user_2301", "userName": "词库达人", "avatarUrl": "https://picsum.photos/100/100?random=44", "content": "词库很全,生僻字也能打出来", "likeCount": 234, "isLiked": false, "createTime": 1735110000, "replies": []}, + {"id": "comment_024", "userId": "user_2401", "userName": "云同步用户", "avatarUrl": "https://picsum.photos/100/100?random=45", "content": "换手机词库还在,太方便了", "likeCount": 345, "isLiked": false, "createTime": 1735023600, "replies": []}, + {"id": "comment_025", "userId": "user_2501", "userName": "语音输入爱好者", "avatarUrl": "https://picsum.photos/100/100?random=46", "content": "语音识别准确率很高", "likeCount": 456, "isLiked": true, "createTime": 1734937200, "replies": [{"id": "reply_025_1", "userId": "user_2502", "userName": "方言用户", "avatarUrl": "https://picsum.photos/100/100?random=47", "content": "支持方言吗?", "likeCount": 23, "isLiked": false, "createTime": 1734940800}]}, + {"id": "comment_026", "userId": "user_2601", "userName": "剪贴板用户", "avatarUrl": "https://picsum.photos/100/100?random=48", "content": "剪贴板历史功能太实用了", "likeCount": 678, "isLiked": false, "createTime": 1734850800, "replies": []}, + {"id": "comment_027", "userId": "user_2701", "userName": "快捷短语用户", "avatarUrl": "https://picsum.photos/100/100?random=49", "content": "自定义短语省了很多时间", "likeCount": 234, "isLiked": false, "createTime": 1734764400, "replies": [{"id": "reply_027_1", "userId": "user_2702", "userName": "客服人员", "avatarUrl": "https://picsum.photos/100/100?random=50", "content": "工作必备功能", "likeCount": 15, "isLiked": false, "createTime": 1734768000}]}, + {"id": "comment_028", "userId": "user_2801", "userName": "单手党", "avatarUrl": "https://picsum.photos/100/100?random=51", "content": "单手模式很贴心", "likeCount": 345, "isLiked": true, "createTime": 1734678000, "replies": []}, + {"id": "comment_029", "userId": "user_2901", "userName": "大屏用户", "avatarUrl": "https://picsum.photos/100/100?random=52", "content": "平板上也很好用", "likeCount": 123, "isLiked": false, "createTime": 1734591600, "replies": []}, + {"id": "comment_030", "userId": "user_3001", "userName": "自定义爱好者", "avatarUrl": "https://picsum.photos/100/100?random=53", "content": "键盘高度可以调节太好了", "likeCount": 456, "isLiked": false, "createTime": 1734505200, "replies": [{"id": "reply_030_1", "userId": "user_3002", "userName": "小手用户", "avatarUrl": "https://picsum.photos/100/100?random=54", "content": "终于不用够着打字了", "likeCount": 34, "isLiked": false, "createTime": 1734508800}]}, + {"id": "comment_031", "userId": "user_3101", "userName": "符号达人", "avatarUrl": "https://picsum.photos/100/100?random=55", "content": "特殊符号很全", "likeCount": 89, "isLiked": false, "createTime": 1734418800, "replies": []}, + {"id": "comment_032", "userId": "user_3201", "userName": "数学老师", "avatarUrl": "https://picsum.photos/100/100?random=56", "content": "数学符号输入方便", "likeCount": 234, "isLiked": true, "createTime": 1734332400, "replies": [{"id": "reply_032_1", "userId": "user_3202", "userName": "学生", "avatarUrl": "https://picsum.photos/100/100?random=57", "content": "老师好", "likeCount": 5, "isLiked": false, "createTime": 1734336000}]}, + {"id": "comment_033", "userId": "user_3301", "userName": "翻译工作者", "avatarUrl": "https://picsum.photos/100/100?random=58", "content": "实时翻译功能很强", "likeCount": 567, "isLiked": false, "createTime": 1734246000, "replies": []}, + {"id": "comment_034", "userId": "user_3401", "userName": "纠错达人", "avatarUrl": "https://picsum.photos/100/100?random=59", "content": "自动纠错很智能", "likeCount": 345, "isLiked": false, "createTime": 1734159600, "replies": []}, + {"id": "comment_035", "userId": "user_3501", "userName": "联想输入用户", "avatarUrl": "https://picsum.photos/100/100?random=60", "content": "联想词很准确", "likeCount": 456, "isLiked": true, "createTime": 1734073200, "replies": [{"id": "reply_035_1", "userId": "user_3502", "userName": "AI爱好者", "avatarUrl": "https://picsum.photos/100/100?random=61", "content": "应该是用了AI", "likeCount": 23, "isLiked": false, "createTime": 1734076800}]}, + {"id": "comment_036", "userId": "user_3601", "userName": "手写输入用户", "avatarUrl": "https://picsum.photos/100/100?random=62", "content": "手写识别很准", "likeCount": 234, "isLiked": false, "createTime": 1733986800, "replies": []}, + {"id": "comment_037", "userId": "user_3701", "userName": "五笔用户", "avatarUrl": "https://picsum.photos/100/100?random=63", "content": "五笔输入法终于有了", "likeCount": 345, "isLiked": false, "createTime": 1733900400, "replies": [{"id": "reply_037_1", "userId": "user_3702", "userName": "老五笔", "avatarUrl": "https://picsum.photos/100/100?random=64", "content": "86版还是98版?", "likeCount": 12, "isLiked": false, "createTime": 1733904000}, {"id": "reply_037_2", "userId": "user_3701", "userName": "五笔用户", "avatarUrl": "https://picsum.photos/100/100?random=63", "content": "都支持", "replyToUserName": "老五笔", "likeCount": 8, "isLiked": false, "createTime": 1733907600}]}, + {"id": "comment_038", "userId": "user_3801", "userName": "双拼用户", "avatarUrl": "https://picsum.photos/100/100?random=65", "content": "双拼方案很全", "likeCount": 456, "isLiked": true, "createTime": 1733814000, "replies": []}, + {"id": "comment_039", "userId": "user_3901", "userName": "九宫格用户", "avatarUrl": "https://picsum.photos/100/100?random=66", "content": "九宫格布局很经典", "likeCount": 123, "isLiked": false, "createTime": 1733727600, "replies": []}, + {"id": "comment_040", "userId": "user_4001", "userName": "26键用户", "avatarUrl": "https://picsum.photos/100/100?random=67", "content": "全键盘手感最好", "likeCount": 567, "isLiked": false, "createTime": 1733641200, "replies": [{"id": "reply_040_1", "userId": "user_4002", "userName": "同意", "avatarUrl": "https://picsum.photos/100/100?random=68", "content": "习惯了就回不去了", "likeCount": 34, "isLiked": false, "createTime": 1733644800}]}, + {"id": "comment_041", "userId": "user_4101", "userName": "GIF达人", "avatarUrl": "https://picsum.photos/100/100?random=69", "content": "GIF搜索太好玩了", "likeCount": 678, "isLiked": true, "createTime": 1733554800, "replies": []}, + {"id": "comment_042", "userId": "user_4201", "userName": "斗图高手", "avatarUrl": "https://picsum.photos/100/100?random=70", "content": "表情包库很丰富", "likeCount": 890, "isLiked": false, "createTime": 1733468400, "replies": [{"id": "reply_042_1", "userId": "user_4202", "userName": "表情收藏家", "avatarUrl": "https://picsum.photos/100/100?random=71", "content": "可以自己添加吗?", "likeCount": 23, "isLiked": false, "createTime": 1733472000}]}, + {"id": "comment_043", "userId": "user_4301", "userName": "字体爱好者", "avatarUrl": "https://picsum.photos/100/100?random=72", "content": "字体选择很多", "likeCount": 234, "isLiked": false, "createTime": 1733382000, "replies": []}, + {"id": "comment_044", "userId": "user_4401", "userName": "音效控", "avatarUrl": "https://picsum.photos/100/100?random=73", "content": "按键音效很舒服", "likeCount": 345, "isLiked": false, "createTime": 1733295600, "replies": []}, + {"id": "comment_045", "userId": "user_4501", "userName": "省电达人", "avatarUrl": "https://picsum.photos/100/100?random=74", "content": "耗电量很低", "likeCount": 456, "isLiked": true, "createTime": 1733209200, "replies": [{"id": "reply_045_1", "userId": "user_4502", "userName": "续航焦虑", "avatarUrl": "https://picsum.photos/100/100?random=75", "content": "这点很重要", "likeCount": 45, "isLiked": false, "createTime": 1733212800}]}, + {"id": "comment_046", "userId": "user_4601", "userName": "启动速度测试", "avatarUrl": "https://picsum.photos/100/100?random=76", "content": "启动速度很快", "likeCount": 567, "isLiked": false, "createTime": 1733122800, "replies": []}, + {"id": "comment_047", "userId": "user_4701", "userName": "稳定性测试", "avatarUrl": "https://picsum.photos/100/100?random=77", "content": "用了半年没崩溃过", "likeCount": 678, "isLiked": false, "createTime": 1733036400, "replies": [{"id": "reply_047_1", "userId": "user_4702", "userName": "开发者", "avatarUrl": "https://picsum.photos/100/100?random=78", "content": "感谢认可", "likeCount": 56, "isLiked": false, "createTime": 1733040000}]}, + {"id": "comment_048", "userId": "user_4801", "userName": "更新频率观察", "avatarUrl": "https://picsum.photos/100/100?random=79", "content": "更新很勤快,bug修复及时", "likeCount": 345, "isLiked": true, "createTime": 1732950000, "replies": []}, + {"id": "comment_049", "userId": "user_4901", "userName": "客服体验", "avatarUrl": "https://picsum.photos/100/100?random=80", "content": "客服回复很快", "likeCount": 234, "isLiked": false, "createTime": 1732863600, "replies": []}, + {"id": "comment_050", "userId": "user_5001", "userName": "社区用户", "avatarUrl": "https://picsum.photos/100/100?random=81", "content": "用户社区很活跃", "likeCount": 456, "isLiked": false, "createTime": 1732777200, "replies": [{"id": "reply_050_1", "userId": "user_5002", "userName": "社区管理", "avatarUrl": "https://picsum.photos/100/100?random=82", "content": "欢迎多交流", "likeCount": 23, "isLiked": false, "createTime": 1732780800}]}, + {"id": "comment_051", "userId": "user_5101", "userName": "推荐达人", "avatarUrl": "https://picsum.photos/100/100?random=83", "content": "已经推荐给所有朋友了", "likeCount": 789, "isLiked": true, "createTime": 1732690800, "replies": []}, + {"id": "comment_052", "userId": "user_5201", "userName": "对比测试", "avatarUrl": "https://picsum.photos/100/100?random=84", "content": "对比了好几款,这个最好用", "likeCount": 890, "isLiked": false, "createTime": 1732604400, "replies": [{"id": "reply_052_1", "userId": "user_5202", "userName": "选择困难", "avatarUrl": "https://picsum.photos/100/100?random=85", "content": "对比了哪些?", "likeCount": 12, "isLiked": false, "createTime": 1732608000}, {"id": "reply_052_2", "userId": "user_5201", "userName": "对比测试", "avatarUrl": "https://picsum.photos/100/100?random=84", "content": "市面上主流的都试过了", "replyToUserName": "选择困难", "likeCount": 8, "isLiked": false, "createTime": 1732611600}]}, + {"id": "comment_053", "userId": "user_5301", "userName": "长期用户", "avatarUrl": "https://picsum.photos/100/100?random=86", "content": "从1.0版本用到现在", "likeCount": 567, "isLiked": false, "createTime": 1732518000, "replies": []}, + {"id": "comment_054", "userId": "user_5401", "userName": "功能建议", "avatarUrl": "https://picsum.photos/100/100?random=87", "content": "希望能加个计算器功能", "likeCount": 234, "isLiked": false, "createTime": 1732431600, "replies": [{"id": "reply_054_1", "userId": "user_5402", "userName": "产品经理", "avatarUrl": "https://picsum.photos/100/100?random=88", "content": "已记录,感谢建议", "likeCount": 45, "isLiked": false, "createTime": 1732435200}]}, + {"id": "comment_055", "userId": "user_5501", "userName": "最后一条", "avatarUrl": "https://picsum.photos/100/100?random=89", "content": "五星好评!", "likeCount": 1234, "isLiked": true, "createTime": 1732345200, "replies": []} ] } diff --git a/keyBoard/Class/AiTalk/V/KBAICommentFooterView.m b/keyBoard/Class/AiTalk/V/KBAICommentFooterView.m index 5c2d6e1..08872ac 100644 --- a/keyBoard/Class/AiTalk/V/KBAICommentFooterView.m +++ b/keyBoard/Class/AiTalk/V/KBAICommentFooterView.m @@ -67,16 +67,6 @@ forState:UIControlStateNormal]; break; } - case KBAIReplyFooterStateLoadMore: { - self.actionButton.hidden = NO; - NSInteger remaining = - comment.totalReplyCount - comment.displayedReplies.count; - title = - [NSString stringWithFormat:@"展开更多回复 (%ld条)", (long)remaining]; - [self.actionButton setImage:[UIImage systemImageNamed:@"chevron.down"] - forState:UIControlStateNormal]; - break; - } case KBAIReplyFooterStateCollapse: { self.actionButton.hidden = NO; title = @"收起"; diff --git a/keyBoard/Class/AiTalk/V/KBAICommentHeaderView.m b/keyBoard/Class/AiTalk/V/KBAICommentHeaderView.m index 331a4a6..dd2a84e 100644 --- a/keyBoard/Class/AiTalk/V/KBAICommentHeaderView.m +++ b/keyBoard/Class/AiTalk/V/KBAICommentHeaderView.m @@ -62,7 +62,7 @@ make.left.equalTo(self.userNameLabel); make.top.equalTo(self.timeLabel.mas_bottom).offset(8); make.right.equalTo(self.contentView).offset(-50); - make.bottom.equalTo(self.contentView).offset(-12); + make.bottom.equalTo(self.contentView).offset(-12).priority(MASLayoutPriorityDefaultHigh); }]; [self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) { diff --git a/keyBoard/Class/AiTalk/V/KBAICommentView.m b/keyBoard/Class/AiTalk/V/KBAICommentView.m index 283dc93..c8b25ad 100644 --- a/keyBoard/Class/AiTalk/V/KBAICommentView.m +++ b/keyBoard/Class/AiTalk/V/KBAICommentView.m @@ -19,15 +19,12 @@ static NSString *const kCommentHeaderIdentifier = @"CommentHeader"; static NSString *const kReplyCellIdentifier = @"ReplyCell"; static NSString *const kCommentFooterIdentifier = @"CommentFooter"; -/// 每次展开的回复数量 -static NSInteger const kRepliesLoadCount = 3; - @interface KBAICommentView () @property(nonatomic, strong) UIView *headerView; @property(nonatomic, strong) UILabel *titleLabel; @property(nonatomic, strong) UIButton *closeButton; -@property(nonatomic, strong) UITableView *tableView; +@property(nonatomic, strong) BaseTableView *tableView; @property(nonatomic, strong) KBAICommentInputView *inputView; @property(nonatomic, strong) NSMutableArray *comments; @@ -184,8 +181,21 @@ static NSInteger const kRepliesLoadCount = 3; NSArray *commentsArray = json[@"comments"]; [self.comments removeAllObjects]; + + // 获取 tableView 宽度用于计算高度 + CGFloat tableWidth = self.tableView.bounds.size.width; + if (tableWidth <= 0) { + tableWidth = [UIScreen mainScreen].bounds.size.width; + } + for (NSDictionary *dict in commentsArray) { KBAICommentModel *comment = [KBAICommentModel mj_objectWithKeyValues:dict]; + // 预先计算并缓存 Header 高度 + comment.cachedHeaderHeight = [comment calculateHeaderHeightWithMaxWidth:tableWidth]; + // 预先计算并缓存所有 Reply 高度 + for (KBAIReplyModel *reply in comment.replies) { + reply.cachedCellHeight = [reply calculateCellHeightWithMaxWidth:tableWidth]; + } [self.comments addObject:comment]; } @@ -268,7 +278,6 @@ static NSInteger const kRepliesLoadCount = 3; // 无二级评论时返回空视图 if (state == KBAIReplyFooterStateHidden) { - NSLog(@"[KBAICommentView] footer hidden section=%ld", (long)section); return nil; } @@ -286,7 +295,15 @@ static NSInteger const kRepliesLoadCount = 3; - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - return UITableViewAutomaticDimension; + KBAICommentModel *comment = self.comments[section]; + return comment.cachedHeaderHeight; +} + +- (CGFloat)tableView:(UITableView *)tableView + heightForRowAtIndexPath:(NSIndexPath *)indexPath { + KBAICommentModel *comment = self.comments[indexPath.section]; + KBAIReplyModel *reply = comment.displayedReplies[indexPath.row]; + return reply.cachedCellHeight; } - (CGFloat)tableView:(UITableView *)tableView @@ -300,16 +317,6 @@ static NSInteger const kRepliesLoadCount = 3; return 30; } -- (CGFloat)tableView:(UITableView *)tableView - estimatedHeightForHeaderInSection:(NSInteger)section { - return 100; -} - -- (CGFloat)tableView:(UITableView *)tableView - estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath { - return 60; -} - #pragma mark - Footer Actions - (void)handleFooterActionForSection:(NSInteger)section { @@ -317,9 +324,8 @@ static NSInteger const kRepliesLoadCount = 3; KBAIReplyFooterState state = [comment footerState]; switch (state) { - case KBAIReplyFooterStateExpand: - case KBAIReplyFooterStateLoadMore: { - [self loadMoreRepliesForSection:section]; + case KBAIReplyFooterStateExpand: { + [self expandRepliesForSection:section]; break; } case KBAIReplyFooterStateCollapse: { @@ -331,115 +337,30 @@ static NSInteger const kRepliesLoadCount = 3; } } -- (void)loadMoreRepliesForSection:(NSInteger)section { +- (void)expandRepliesForSection:(NSInteger)section { KBAICommentModel *comment = self.comments[section]; - NSInteger currentCount = comment.displayedReplies.count; - NSDictionary *anchor = [self captureHeaderAnchorForSection:section]; - - NSLog(@"[KBAICommentView] loadMore(before) section=%ld offsetY=%.2f contentSizeH=%.2f boundsH=%.2f rows=%ld", - (long)section, - self.tableView.contentOffset.y, - self.tableView.contentSize.height, - self.tableView.bounds.size.height, - (long)currentCount); - - // 加载更多 - [comment loadMoreReplies:kRepliesLoadCount]; - - // 计算新增的行 - NSInteger newCount = comment.displayedReplies.count; - NSMutableArray *insertIndexPaths = [NSMutableArray array]; - for (NSInteger i = currentCount; i < newCount; i++) { - [insertIndexPaths addObject:[NSIndexPath indexPathForRow:i - inSection:section]]; - } - - // 更新(带轻微动画) - [self.tableView beginUpdates]; - if (insertIndexPaths.count > 0) { - [self.tableView insertRowsAtIndexPaths:insertIndexPaths - withRowAnimation:UITableViewRowAnimationFade]; - } - [self.tableView endUpdates]; - [self.tableView layoutIfNeeded]; - [self restoreHeaderAnchor:anchor]; - - NSLog(@"[KBAICommentView] loadMore(after) section=%ld offsetY=%.2f contentSizeH=%.2f boundsH=%.2f rows=%ld", - (long)section, - self.tableView.contentOffset.y, - self.tableView.contentSize.height, - self.tableView.bounds.size.height, - (long)comment.displayedReplies.count); - dispatch_async(dispatch_get_main_queue(), ^{ - NSLog(@"[KBAICommentView] loadMore(next) section=%ld offsetY=%.2f contentSizeH=%.2f boundsH=%.2f viewBoundsH=%.2f", - (long)section, - self.tableView.contentOffset.y, - self.tableView.contentSize.height, - self.tableView.bounds.size.height, - self.bounds.size.height); - }); - - // 手动刷新 Footer(避免使用 reloadSections 导致滚动) - KBAICommentFooterView *footerView = - (KBAICommentFooterView *)[self.tableView footerViewForSection:section]; - if (footerView) { - [footerView configureWithComment:comment]; - } + + // 一次性展开全部回复 + [comment expandAllReplies]; + + // 直接刷新该 section +// [UIView performWithoutAnimation:^{ + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] + withRowAnimation:UITableViewRowAnimationAutomatic]; +// }]; } - (void)collapseRepliesForSection:(NSInteger)section { KBAICommentModel *comment = self.comments[section]; - NSInteger rowCount = comment.displayedReplies.count; - NSDictionary *anchor = [self captureHeaderAnchorForSection:section]; - - NSLog(@"[KBAICommentView] collapse(before) section=%ld offsetY=%.2f contentSizeH=%.2f boundsH=%.2f rows=%ld", - (long)section, - self.tableView.contentOffset.y, - self.tableView.contentSize.height, - self.tableView.bounds.size.height, - (long)rowCount); - - // 计算要删除的行 - NSMutableArray *deleteIndexPaths = [NSMutableArray array]; - for (NSInteger i = 0; i < rowCount; i++) { - [deleteIndexPaths addObject:[NSIndexPath indexPathForRow:i - inSection:section]]; - } - - // 收起回复 + + // 收起全部回复 [comment collapseReplies]; - - // 删除行(带轻微动画) - [self.tableView beginUpdates]; - if (deleteIndexPaths.count > 0) { - [self.tableView deleteRowsAtIndexPaths:deleteIndexPaths - withRowAnimation:UITableViewRowAnimationFade]; - } - [self.tableView endUpdates]; - [self.tableView layoutIfNeeded]; - [self restoreHeaderAnchor:anchor]; - - NSLog(@"[KBAICommentView] collapse(after) section=%ld offsetY=%.2f contentSizeH=%.2f boundsH=%.2f rows=%ld", - (long)section, - self.tableView.contentOffset.y, - self.tableView.contentSize.height, - self.tableView.bounds.size.height, - (long)comment.displayedReplies.count); - dispatch_async(dispatch_get_main_queue(), ^{ - NSLog(@"[KBAICommentView] collapse(next) section=%ld offsetY=%.2f contentSizeH=%.2f boundsH=%.2f viewBoundsH=%.2f", - (long)section, - self.tableView.contentOffset.y, - self.tableView.contentSize.height, - self.tableView.bounds.size.height, - self.bounds.size.height); - }); - - // 手动刷新 Footer(避免使用 reloadSections 导致滚动) - KBAICommentFooterView *footerView = - (KBAICommentFooterView *)[self.tableView footerViewForSection:section]; - if (footerView) { - [footerView configureWithComment:comment]; - } + + // 直接刷新该 section +// [UIView performWithoutAnimation:^{ + [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] + withRowAnimation:UITableViewRowAnimationAutomatic]; +// }]; } #pragma mark - Actions @@ -484,20 +405,14 @@ static NSInteger const kRepliesLoadCount = 3; return _closeButton; } -- (UITableView *)tableView { +- (BaseTableView *)tableView { if (!_tableView) { - _tableView = [[UITableView alloc] initWithFrame:CGRectZero + _tableView = [[BaseTableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; _tableView.dataSource = self; _tableView.delegate = self; _tableView.backgroundColor = [UIColor whiteColor]; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - _tableView.estimatedRowHeight = 0; - _tableView.rowHeight = UITableViewAutomaticDimension; - _tableView.estimatedSectionHeaderHeight = 0; - _tableView.estimatedSectionFooterHeight = 0; - _tableView.sectionHeaderHeight = UITableViewAutomaticDimension; - _tableView.sectionFooterHeight = UITableViewAutomaticDimension; _tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; // 注册 Header/Cell/Footer @@ -531,81 +446,4 @@ static NSInteger const kRepliesLoadCount = 3; return _inputView; } -#pragma mark - Header Anchor - -- (NSDictionary *)captureHeaderAnchorForSection:(NSInteger)section { - CGRect rect = [self.tableView rectForHeaderInSection:section]; - NSLog(@"[KBAICommentView] anchor capture(header) section=%ld rect=%@ offsetY=%.2f contentSizeH=%.2f boundsH=%.2f", - (long)section, - NSStringFromCGRect(rect), - self.tableView.contentOffset.y, - self.tableView.contentSize.height, - self.tableView.bounds.size.height); - if (CGRectIsEmpty(rect) || CGRectIsNull(rect)) { - NSLog(@"[KBAICommentView] anchor capture(header) empty section=%ld", - (long)section); - return nil; - } - - CGFloat offset = self.tableView.contentOffset.y - rect.origin.y; - return @{ - @"section" : @(section), - @"offset" : @(offset), - @"fallbackOffset" : @(self.tableView.contentOffset.y) - }; -} - -- (void)restoreHeaderAnchor:(NSDictionary *)anchor { - if (!anchor) { - NSLog(@"[KBAICommentView] anchor restore(header) skipped (nil)"); - return; - } - - NSInteger section = [anchor[@"section"] integerValue]; - if (section < 0 || section >= self.comments.count) { - NSLog(@"[KBAICommentView] anchor restore(header) invalid section=%ld", - (long)section); - return; - } - - CGRect rect = [self.tableView rectForHeaderInSection:section]; - NSLog(@"[KBAICommentView] anchor restore(header) section=%ld rect=%@", - (long)section, - NSStringFromCGRect(rect)); - if (CGRectIsEmpty(rect) || CGRectIsNull(rect)) { - NSNumber *fallbackOffset = anchor[@"fallbackOffset"]; - if (!fallbackOffset) { - NSLog(@"[KBAICommentView] anchor restore(header) no fallback section=%ld", - (long)section); - return; - } - NSLog(@"[KBAICommentView] anchor restore(header) fallback section=%ld offsetY=%.2f", - (long)section, - [fallbackOffset doubleValue]); - [self setTableViewOffset:[fallbackOffset doubleValue]]; - return; - } - - CGFloat targetOffsetY = rect.origin.y + [anchor[@"offset"] doubleValue]; - NSLog(@"[KBAICommentView] anchor restore(header) target section=%ld targetY=%.2f", - (long)section, - targetOffsetY); - [self setTableViewOffset:targetOffsetY]; -} - -- (void)setTableViewOffset:(CGFloat)offsetY { - UIEdgeInsets inset = self.tableView.adjustedContentInset; - CGFloat minOffsetY = -inset.top; - CGFloat maxOffsetY = - MAX(minOffsetY, self.tableView.contentSize.height + inset.bottom - - self.tableView.bounds.size.height); - CGFloat targetOffsetY = MIN(MAX(offsetY, minOffsetY), maxOffsetY); - NSLog(@"[KBAICommentView] set offset target=%.2f min=%.2f max=%.2f", - targetOffsetY, - minOffsetY, - maxOffsetY); - [self.tableView setContentOffset:CGPointMake(0, targetOffsetY) - animated:NO]; -} - @end diff --git a/keyBoard/Class/AiTalk/V/KBAIReplyCell.m b/keyBoard/Class/AiTalk/V/KBAIReplyCell.m index 2cd1b1b..2794844 100644 --- a/keyBoard/Class/AiTalk/V/KBAIReplyCell.m +++ b/keyBoard/Class/AiTalk/V/KBAIReplyCell.m @@ -56,7 +56,8 @@ [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentLabel); make.top.equalTo(self.contentLabel.mas_bottom).offset(4); - make.bottom.equalTo(self.contentView).offset(-8); + // 降低优先级,避免与 TableView 设置的固定高度约束冲突 + make.bottom.equalTo(self.contentView).offset(-8).priority(MASLayoutPriorityDefaultHigh); }]; [self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {