ios - 使用估计的行高时将 UITableView 滚动到底部

标签 ios uitableview

我遇到了一个看起来不应该成为问题的问题。我正在尝试为我的应用程序创建评论(“聊天”) View ,但我使用的是估计的行高,无法找到让评论从底部开始的好方法,这样在加载 View 时, 最新的评论在屏幕底部,输入区域的正上方也在屏幕底部。

我已经四处寻找多年,并找到了如下解决方案:

[self.tblComments scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

效果不佳,因为它使用了估计的行高,这并不总是正确的(有些评论会更长)。

[self.tblComments setContentInset:UIEdgeInsetsMake(self.tblComments.bounds.size.height - self.tblComments.contentSize.height, 0, 0, 0)];

同上问题(contentSize由estimatedRowHeight决定)

我敢肯定在某个地方有一个完美的解决方案,因为很多应用程序都有这样的 View ,我就是找不到。我很想深入了解我可能在这里遗漏的东西......

最佳答案

编辑:

contentSize 就是 "The size of the content view."但是由于您已经为 estimatedRowHeight 设置了一个值,因此所有屏幕外单元格的高度都假定为 estimatedRowHeight

根据文档,这是 estimatedRowHeight 的要点:

Providing a nonnegative estimate of the height of rows can improve the performance of loading the table view. If the table contains variable height rows, it might be expensive to calculate all their heights when the table loads. Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time.

所以基本上,为了节省时间,该表根据您的 estimatedRowHeight 假设行高和内容大小。通过使用 estimatedRowHeight,您要求您的 UITableView 创建这些“快捷方式”以提高性能。您基本上是在告诉程序不要提前计算行高,因此为了获得任何屏幕外内容的行高和内容大小,您必须手动计算它们。只要您决定设置一个 estimatedRowHeight,这是不可避免的。

我猜你看过的许多聊天应用程序都不使用 estimatedRowHeight 来避免这个问题......

但如果您确实觉得使用 estimatedRowHeight 有助于提高应用的性能,这里有两个建议。

建议 #1

也许有一个 totalChatHeight 变量是有意义的,您可以在其中跟踪总行高,因为它们使用与您的 heightForRowAtIndexPath: 方法类似的逻辑计算。通过最初在评论加载时在后台计算此信息,然后随着您的进行递增,您仍然可以保持使用 estimatedRowHeight 的性能优势,而不会牺牲让表格知道其行高的功能。

通过这样做,您可以像这样构造您的 contentOffset 语句以使用已知的表格行高信息滚动到底部:

CGPoint bottomOffset = CGPointMake(0, totalChatHeight - self.tblComments.frame.size.height);
[self.tblComments setContentOffset:bottomOffset animated:YES];

建议 #2

另一个建议是动态计算行平均值,这样您就可以更精确地测量 estimatedRowHeightUITableViewcontentSize使用或不使用 estimatedRowHeight 大致相同。这样 estimatedRowHeight 就是实际上估计的行高,估计的内容大小也应该接近实际的 contentSize,所以这个标准的 contentOffset 公式应该有效:

CGPoint bottomOffset = CGPointMake(0, self.tblComments.contentSize.height - self.tblComments.frame.size.height);
[self.tblComments setContentOffset:bottomOffset animated:YES];

尽管随着聊天记录和舍入误差的增长,这可能是危险的。

建议 #3 <-- 在这种情况下也许是最好的方法

第三个建议在您的案例中可能是最容易实现的,因为它不需要任何持续的计算:

在重新加载表格数据之前,只需将 estimatedRowHeight 设置为最后一行的高度。

您可以使用在 heightForRowAtIndexPath: 中使用的任何算法来计算新行的高度,然后将 estimatedRowHeight 设置为该高度;这样你就可以使用这个语句滚动到最后一个单元格

[self.tblComments scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

即使如您所说,它根据 estimatedRowHeight 确定行位置,只要 estimatedRowHeight 等于底行,它就应该滚动到正确的位置高度。

关于ios - 使用估计的行高时将 UITableView 滚动到底部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27204190/

相关文章:

ios - 2 型蹦床用完

ios - 选择时 View 从 UITableViewCell 中消失

ios - 使用来自其他 View 的查询过滤 TableView

ios - 在 tableview 的 swift 文件之间快速传递数组

objective-c - 使用数组传递数据但在 TableView 委托(delegate)中显示为空

ios - Interface Builder 文件 xcode 8 中的未知类 CustomUITableViewCell

objective-c - 保存托管对象上下文会在iOS 5的performBlock中创建死锁

ios - 如何在 Xcode 中调试 EXC_BREAKPOINT (SIGTRAP)

ios - 什么是 objc_AssociationPolicy?它是如何工作的?

ios - UIPickerView 行为异常