修改bug
This commit is contained in:
@@ -64,9 +64,16 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
||||
self.tableView.delegate = self;
|
||||
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
self.tableView.backgroundColor = [UIColor clearColor];
|
||||
self.tableView.estimatedRowHeight = 60;
|
||||
// 关键修复:使用合理的估算高度(避免抖动,但不能为0)
|
||||
self.tableView.estimatedRowHeight = 80;
|
||||
self.tableView.estimatedSectionHeaderHeight = 0;
|
||||
self.tableView.estimatedSectionFooterHeight = 0;
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.showsVerticalScrollIndicator = YES;
|
||||
// 关键修复:禁用内容自动调整,防止与外层 CollectionView 冲突
|
||||
if (@available(iOS 11.0, *)) {
|
||||
self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
|
||||
}
|
||||
[self addSubview:self.tableView];
|
||||
|
||||
// 注册 Cell
|
||||
@@ -182,13 +189,22 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
||||
}
|
||||
|
||||
- (void)scrollToBottom {
|
||||
[self scrollToBottomAnimated:YES];
|
||||
}
|
||||
|
||||
- (void)scrollToBottomAnimated:(BOOL)animated {
|
||||
if (self.messages.count == 0) return;
|
||||
|
||||
// 关键修复:使用 layoutIfNeeded 确保布局完成后再滚动
|
||||
[self.tableView layoutIfNeeded];
|
||||
|
||||
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.messages.count - 1
|
||||
inSection:0];
|
||||
|
||||
// 直接滚动到最后一条消息,不检查是否可见(确保新消息能被看到)
|
||||
[self.tableView scrollToRowAtIndexPath:lastIndexPath
|
||||
atScrollPosition:UITableViewScrollPositionBottom
|
||||
animated:YES];
|
||||
animated:animated];
|
||||
}
|
||||
|
||||
#pragma mark - Public Helpers
|
||||
@@ -240,6 +256,10 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
||||
for (NSInteger i = oldCount; i < newCount; i++) {
|
||||
[indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
|
||||
}
|
||||
|
||||
// 关键修复:批量插入前先布局,避免高度计算不准确
|
||||
[self.tableView layoutIfNeeded];
|
||||
|
||||
[self.tableView insertRowsAtIndexPaths:indexPaths
|
||||
withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
@@ -247,8 +267,10 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
||||
[self updateFooterVisibility];
|
||||
|
||||
if (autoScroll) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[self scrollToBottom];
|
||||
// 关键修复:插入完成后立即滚动,使用 dispatch_async 确保插入动画完成
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.tableView layoutIfNeeded]; // 再次确保布局完成
|
||||
[self scrollToBottomAnimated:YES];
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -274,14 +296,14 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
||||
CGFloat newContentHeight = self.tableView.contentSize.height;
|
||||
CGFloat delta = newContentHeight - oldContentHeight;
|
||||
CGFloat offsetY = oldOffsetY + delta;
|
||||
// 关键修复:使用非动画方式设置 offset,避免抖动
|
||||
[self.tableView setContentOffset:CGPointMake(0, offsetY) animated:NO];
|
||||
return;
|
||||
}
|
||||
|
||||
if (scrollToBottom) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[self scrollToBottom];
|
||||
});
|
||||
// 关键修复:直接滚动,不使用延迟
|
||||
[self scrollToBottomAnimated:NO];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,6 +452,31 @@ static const NSTimeInterval kTimestampInterval = 5 * 60; // 5 分钟
|
||||
}
|
||||
}
|
||||
|
||||
/// 关键修复:优化嵌套滚动体验,减少边界弹簧效果导致的抖动
|
||||
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
|
||||
withVelocity:(CGPoint)velocity
|
||||
targetContentOffset:(inout CGPoint *)targetContentOffset {
|
||||
|
||||
CGFloat offsetY = scrollView.contentOffset.y;
|
||||
CGFloat contentHeight = scrollView.contentSize.height;
|
||||
CGFloat scrollViewHeight = scrollView.bounds.size.height;
|
||||
|
||||
// 如果内容不够长,禁用弹簧效果
|
||||
if (contentHeight <= scrollViewHeight) {
|
||||
scrollView.bounces = NO;
|
||||
} else {
|
||||
scrollView.bounces = YES;
|
||||
|
||||
// 在快速滑动到底部时,避免过度弹簧导致抖动
|
||||
if (velocity.y < 0) { // 向上滑动(到底部)
|
||||
CGFloat maxOffset = contentHeight - scrollViewHeight + scrollView.contentInset.bottom;
|
||||
if (targetContentOffset->y > maxOffset) {
|
||||
targetContentOffset->y = maxOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - KBChatAssistantMessageCellDelegate
|
||||
|
||||
- (void)assistantMessageCell:(KBChatAssistantMessageCell *)cell
|
||||
|
||||
Reference in New Issue
Block a user