处理好评论了

This commit is contained in:
2026-01-16 19:09:54 +08:00
parent 619c02f236
commit 3dfb8f31e2
9 changed files with 211 additions and 402 deletions

View File

@@ -14,9 +14,8 @@ NS_ASSUME_NONNULL_BEGIN
/// Footer 状态枚举 /// Footer 状态枚举
typedef NS_ENUM(NSInteger, KBAIReplyFooterState) { typedef NS_ENUM(NSInteger, KBAIReplyFooterState) {
KBAIReplyFooterStateHidden, // 无二级评论,不显示 KBAIReplyFooterStateHidden, // 无二级评论,不显示
KBAIReplyFooterStateExpand, // 显示"展开x条回复"初始折叠状态) KBAIReplyFooterStateExpand, // 显示"展开x条回复"(折叠状态)
KBAIReplyFooterStateLoadMore, // 显示"加载更多"展开部分 KBAIReplyFooterStateCollapse // 显示"收起"(展开状态
KBAIReplyFooterStateCollapse // 显示"收起"(全部展开后)
}; };
/// 一级评论模型 /// 一级评论模型
@@ -63,6 +62,11 @@ typedef NS_ENUM(NSInteger, KBAIReplyFooterState) {
/// 回复是否已展开 /// 回复是否已展开
@property(nonatomic, assign) BOOL isRepliesExpanded; @property(nonatomic, assign) BOOL isRepliesExpanded;
#pragma mark - 缓存高度
/// Header 高度缓存
@property(nonatomic, assign) CGFloat cachedHeaderHeight;
#pragma mark - Helper Methods #pragma mark - Helper Methods
/// 格式化后的时间字符串 /// 格式化后的时间字符串
@@ -71,13 +75,16 @@ typedef NS_ENUM(NSInteger, KBAIReplyFooterState) {
/// 获取当前 Footer 状态 /// 获取当前 Footer 状态
- (KBAIReplyFooterState)footerState; - (KBAIReplyFooterState)footerState;
/// 展开更多回复(每次加载指定数量) /// 展开全部回复
/// @param count 本次加载的数量 - (void)expandAllReplies;
- (void)loadMoreReplies:(NSInteger)count;
/// 收起所有回复 /// 收起所有回复
- (void)collapseReplies; - (void)collapseReplies;
/// 计算 Header 高度
/// @param maxWidth 最大宽度
- (CGFloat)calculateHeaderHeightWithMaxWidth:(CGFloat)maxWidth;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -64,37 +64,55 @@
return KBAIReplyFooterStateHidden; return KBAIReplyFooterStateHidden;
} }
// //
if (!self.isRepliesExpanded) { if (self.isRepliesExpanded) {
return KBAIReplyFooterStateExpand;
}
//
if (self.displayedReplies.count < self.totalReplyCount) {
return KBAIReplyFooterStateLoadMore;
}
//
return KBAIReplyFooterStateCollapse; return KBAIReplyFooterStateCollapse;
}
//
return KBAIReplyFooterStateExpand;
} }
- (void)loadMoreReplies:(NSInteger)count { - (void)expandAllReplies {
self.isRepliesExpanded = YES; self.isRepliesExpanded = YES;
[self.displayedReplies removeAllObjects];
NSInteger currentCount = self.displayedReplies.count; [self.displayedReplies addObjectsFromArray:self.replies];
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);
} }
- (void)collapseReplies { - (void)collapseReplies {
self.isRepliesExpanded = NO; self.isRepliesExpanded = NO;
[self.displayedReplies removeAllObjects]; [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 @end

View File

@@ -39,9 +39,18 @@ NS_ASSUME_NONNULL_BEGIN
/// 创建时间(时间戳) /// 创建时间(时间戳)
@property(nonatomic, assign) NSTimeInterval createTime; @property(nonatomic, assign) NSTimeInterval createTime;
#pragma mark - 缓存高度
/// Cell 高度缓存
@property(nonatomic, assign) CGFloat cachedCellHeight;
/// 格式化后的时间字符串 /// 格式化后的时间字符串
- (NSString *)formattedTime; - (NSString *)formattedTime;
/// 计算 Cell 高度
/// @param maxWidth 最大宽度
- (CGFloat)calculateCellHeightWithMaxWidth:(CGFloat)maxWidth;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -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 @end

View File

@@ -1,5 +1,5 @@
{ {
"totalCount": 1258, "totalCount": 5628,
"comments": [ "comments": [
{ {
"id": "comment_001", "id": "comment_001",
@@ -11,77 +11,11 @@
"isLiked": false, "isLiked": false,
"createTime": 1737010800, "createTime": 1737010800,
"replies": [ "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_1", {"id": "reply_001_2", "userId": "user_103", "userName": "程序员小李", "avatarUrl": "https://picsum.photos/100/100?random=3", "content": "感谢支持,会继续努力的!", "replyToUserName": "科技达人", "likeCount": 23, "isLiked": true, "createTime": 1737018000},
"userId": "user_102", {"id": "reply_001_3", "userId": "user_104", "userName": "产品经理", "avatarUrl": "https://picsum.photos/100/100?random=4", "content": "下个版本会有更多惊喜", "likeCount": 12, "isLiked": false, "createTime": 1737021600},
"userName": "科技达人", {"id": "reply_001_4", "userId": "user_105", "userName": "UI设计师", "avatarUrl": "https://picsum.photos/100/100?random=5", "content": "细节决定品质", "likeCount": 8, "isLiked": false, "createTime": 1737025200},
"avatarUrl": "https://picsum.photos/100/100?random=2", {"id": "reply_001_5", "userId": "user_106", "userName": "测试工程师", "avatarUrl": "https://picsum.photos/100/100?random=6", "content": "已经测试通过了,稳定性很好", "likeCount": 5, "isLiked": false, "createTime": 1737028800}
"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
}
] ]
}, },
{ {
@@ -94,60 +28,22 @@
"isLiked": false, "isLiked": false,
"createTime": 1736924400, "createTime": 1736924400,
"replies": [ "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_1", {"id": "reply_002_2", "userId": "user_201", "userName": "热心网友", "avatarUrl": "https://picsum.photos/100/100?random=10", "content": "太好了,期待!", "replyToUserName": "官方客服", "likeCount": 5, "isLiked": false, "createTime": 1736931600}
"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", "id": "comment_004",
"userId": "user_401", "userId": "user_401",
"userName": "效率达人", "userName": "效率达人",
"avatarUrl": "https://picsum.photos/100/100?random=13", "avatarUrl": "https://picsum.photos/100/100?random=13",
"content": "自从用了这个键盘,打字速度提升了一倍!强烈推荐给大家", "content": "自从用了这个键盘,打字速度提升了一倍!强烈推荐",
"likeCount": 512, "likeCount": 512,
"isLiked": false, "isLiked": false,
"createTime": 1736751600, "createTime": 1736751600,
"replies": [ "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, "isLiked": false,
"createTime": 1736665200, "createTime": 1736665200,
"replies": [ "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_1", {"id": "reply_005_2", "userId": "user_503", "userName": "粉丝B", "avatarUrl": "https://picsum.photos/100/100?random=17", "content": "已经去看了,确实很详细", "likeCount": 23, "isLiked": false, "createTime": 1736672400},
"userId": "user_502", {"id": "reply_005_3", "userId": "user_504", "userName": "路人甲", "avatarUrl": "https://picsum.photos/100/100?random=18", "content": "求链接", "likeCount": 8, "isLiked": false, "createTime": 1736676000}
"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", {"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}]},
"userId": "user_601", {"id": "comment_008", "userId": "user_801", "userName": "职场人", "avatarUrl": "https://picsum.photos/100/100?random=22", "content": "工作效率提升神器", "likeCount": 234, "isLiked": true, "createTime": 1736406000, "replies": []},
"userName": "老用户", {"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}]},
"avatarUrl": "https://picsum.photos/100/100?random=19", {"id": "comment_010", "userId": "user_1001", "userName": "文字工作者", "avatarUrl": "https://picsum.photos/100/100?random=25", "content": "写文章必备工具", "likeCount": 156, "isLiked": false, "createTime": 1736233200, "replies": []},
"content": "用了三年了,一直很稳定,希望能出个暗黑主题", {"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}]},
"likeCount": 178, {"id": "comment_012", "userId": "user_1201", "userName": "产品体验官", "avatarUrl": "https://picsum.photos/100/100?random=28", "content": "交互体验非常流畅", "likeCount": 78, "isLiked": false, "createTime": 1736060400, "replies": []},
"isLiked": false, {"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}]},
"createTime": 1736578800, {"id": "comment_014", "userId": "user_1401", "userName": "颜值党", "avatarUrl": "https://picsum.photos/100/100?random=31", "content": "主题皮肤太好看了", "likeCount": 567, "isLiked": true, "createTime": 1735887600, "replies": []},
"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": []}
] ]
} }

View File

@@ -67,16 +67,6 @@
forState:UIControlStateNormal]; forState:UIControlStateNormal];
break; 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: { case KBAIReplyFooterStateCollapse: {
self.actionButton.hidden = NO; self.actionButton.hidden = NO;
title = @"收起"; title = @"收起";

View File

@@ -62,7 +62,7 @@
make.left.equalTo(self.userNameLabel); make.left.equalTo(self.userNameLabel);
make.top.equalTo(self.timeLabel.mas_bottom).offset(8); make.top.equalTo(self.timeLabel.mas_bottom).offset(8);
make.right.equalTo(self.contentView).offset(-50); 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) { [self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {

View File

@@ -19,15 +19,12 @@ static NSString *const kCommentHeaderIdentifier = @"CommentHeader";
static NSString *const kReplyCellIdentifier = @"ReplyCell"; static NSString *const kReplyCellIdentifier = @"ReplyCell";
static NSString *const kCommentFooterIdentifier = @"CommentFooter"; static NSString *const kCommentFooterIdentifier = @"CommentFooter";
///
static NSInteger const kRepliesLoadCount = 3;
@interface KBAICommentView () <UITableViewDataSource, UITableViewDelegate> @interface KBAICommentView () <UITableViewDataSource, UITableViewDelegate>
@property(nonatomic, strong) UIView *headerView; @property(nonatomic, strong) UIView *headerView;
@property(nonatomic, strong) UILabel *titleLabel; @property(nonatomic, strong) UILabel *titleLabel;
@property(nonatomic, strong) UIButton *closeButton; @property(nonatomic, strong) UIButton *closeButton;
@property(nonatomic, strong) UITableView *tableView; @property(nonatomic, strong) BaseTableView *tableView;
@property(nonatomic, strong) KBAICommentInputView *inputView; @property(nonatomic, strong) KBAICommentInputView *inputView;
@property(nonatomic, strong) NSMutableArray<KBAICommentModel *> *comments; @property(nonatomic, strong) NSMutableArray<KBAICommentModel *> *comments;
@@ -184,8 +181,21 @@ static NSInteger const kRepliesLoadCount = 3;
NSArray *commentsArray = json[@"comments"]; NSArray *commentsArray = json[@"comments"];
[self.comments removeAllObjects]; [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) { for (NSDictionary *dict in commentsArray) {
KBAICommentModel *comment = [KBAICommentModel mj_objectWithKeyValues:dict]; 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]; [self.comments addObject:comment];
} }
@@ -268,7 +278,6 @@ static NSInteger const kRepliesLoadCount = 3;
// //
if (state == KBAIReplyFooterStateHidden) { if (state == KBAIReplyFooterStateHidden) {
NSLog(@"[KBAICommentView] footer hidden section=%ld", (long)section);
return nil; return nil;
} }
@@ -286,7 +295,15 @@ static NSInteger const kRepliesLoadCount = 3;
- (CGFloat)tableView:(UITableView *)tableView - (CGFloat)tableView:(UITableView *)tableView
heightForHeaderInSection:(NSInteger)section { 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 - (CGFloat)tableView:(UITableView *)tableView
@@ -300,16 +317,6 @@ static NSInteger const kRepliesLoadCount = 3;
return 30; return 30;
} }
- (CGFloat)tableView:(UITableView *)tableView
estimatedHeightForHeaderInSection:(NSInteger)section {
return 100;
}
- (CGFloat)tableView:(UITableView *)tableView
estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60;
}
#pragma mark - Footer Actions #pragma mark - Footer Actions
- (void)handleFooterActionForSection:(NSInteger)section { - (void)handleFooterActionForSection:(NSInteger)section {
@@ -317,9 +324,8 @@ static NSInteger const kRepliesLoadCount = 3;
KBAIReplyFooterState state = [comment footerState]; KBAIReplyFooterState state = [comment footerState];
switch (state) { switch (state) {
case KBAIReplyFooterStateExpand: case KBAIReplyFooterStateExpand: {
case KBAIReplyFooterStateLoadMore: { [self expandRepliesForSection:section];
[self loadMoreRepliesForSection:section];
break; break;
} }
case KBAIReplyFooterStateCollapse: { case KBAIReplyFooterStateCollapse: {
@@ -331,115 +337,30 @@ static NSInteger const kRepliesLoadCount = 3;
} }
} }
- (void)loadMoreRepliesForSection:(NSInteger)section { - (void)expandRepliesForSection:(NSInteger)section {
KBAICommentModel *comment = self.comments[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, [comment expandAllReplies];
self.tableView.contentOffset.y,
self.tableView.contentSize.height,
self.tableView.bounds.size.height,
(long)currentCount);
// // section
[comment loadMoreReplies:kRepliesLoadCount]; // [UIView performWithoutAnimation:^{
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section]
// withRowAnimation:UITableViewRowAnimationAutomatic];
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];
}
} }
- (void)collapseRepliesForSection:(NSInteger)section { - (void)collapseRepliesForSection:(NSInteger)section {
KBAICommentModel *comment = self.comments[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]; [comment collapseReplies];
// // section
[self.tableView beginUpdates]; // [UIView performWithoutAnimation:^{
if (deleteIndexPaths.count > 0) { [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section]
[self.tableView deleteRowsAtIndexPaths:deleteIndexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
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];
}
} }
#pragma mark - Actions #pragma mark - Actions
@@ -484,20 +405,14 @@ static NSInteger const kRepliesLoadCount = 3;
return _closeButton; return _closeButton;
} }
- (UITableView *)tableView { - (BaseTableView *)tableView {
if (!_tableView) { if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero _tableView = [[BaseTableView alloc] initWithFrame:CGRectZero
style:UITableViewStyleGrouped]; style:UITableViewStyleGrouped];
_tableView.dataSource = self; _tableView.dataSource = self;
_tableView.delegate = self; _tableView.delegate = self;
_tableView.backgroundColor = [UIColor whiteColor]; _tableView.backgroundColor = [UIColor whiteColor];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.estimatedRowHeight = 0;
_tableView.rowHeight = UITableViewAutomaticDimension;
_tableView.estimatedSectionHeaderHeight = 0;
_tableView.estimatedSectionFooterHeight = 0;
_tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
_tableView.sectionFooterHeight = UITableViewAutomaticDimension;
_tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; _tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
// Header/Cell/Footer // Header/Cell/Footer
@@ -531,81 +446,4 @@ static NSInteger const kRepliesLoadCount = 3;
return _inputView; 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 @end

View File

@@ -56,7 +56,8 @@
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentLabel); make.left.equalTo(self.contentLabel);
make.top.equalTo(self.contentLabel.mas_bottom).offset(4); 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) { [self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {