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

我遇到的问题似乎不应该是一个问题.我正在尝试为我的应用程序创建一个评论(“聊天”)视图,但我使用的是估计的行高,并且无法找到一个很好的方法让评论从底部开始,这样当视图加载时,最新评论位于屏幕底部,位于屏幕底部输入区域的正上方.

我一直在寻找很多年,并找到了这样的解决方案:

[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确定).

我确信这个地方有一个完美的解决方案,因为很多应用都有这样的观点,我找不到它.我喜欢任何洞察我可能在这里失踪的东西……

最佳答案 编辑:

contentSize只是“The size of the content view.”但是因为你为estimatedRowHeight设置了一个值,所以你所有的屏幕外单元都被假定为heightRowHeight的高度.

根据文档,这里是估计的高度:

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

另一个建议是动态计算行平均值,以便您对estimatedRowHeight进行更精确的测量,并且无论是否使用estimatedRowHeight,UITableView的contentSize都大致相同.那样估计RowHeight实际上是估计行高,估计的内容大小也应该接近实际的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等于底行高度,它就应滚动到正确的位置.

点赞