使用动态单元格高度时将表格视图滚动到底部

Posted

技术标签:

【中文标题】使用动态单元格高度时将表格视图滚动到底部【英文标题】:Scroll table view to bottom when using dynamic cell height 【发布时间】:2016-06-27 01:17:19 【问题描述】:

使用动态单元格高度时如何将表格视图滚动到底部?

由于某种原因,此代码在这种情况下不起作用:

[self.tableView scrollRectToVisible:CGRectMake(0, self.tableView.contentSize.height - self.tableView.bounds.size.height, self.tableView.bounds.size.width, self.tableView.bounds.size.height) animated:YES];

谢谢!

编辑:使用@Hasiya 的代码滚动到底部,对于你们中的一些人来说,仅此一项就可以解决问题。

【问题讨论】:

[self.tableView setContentOffset:...] 工作吗? 不幸的是…… 试试,tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: arrayData.count, inSection: 0), atScrollPosition: UITableViewScrollPosition.Bottom, 动画: true) 你能指定你的场景不工作吗? 试试这个,如果 (arrayData.count) NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayData.count - 1 inSection:0]; [self.tableView selectRowAtIndexPath:indexPath Animation:YES scrollPosition:UITableViewScrollPositionNone]; [self tableView:self.tableView didSelectRowAtIndexPath:indexPath]; 【参考方案1】:

以下内容适用于我使用 Xcode 8.3.2 的 Swift 3.1 代码,仅针对 iPhone 的 iOS 10.1。

我遇到了和 OP 一样的问题。我的应用程序包含消息传递功能。当消息视图被推入堆栈时,我希望最后一个帖子可见。由于消息的内容,我的表格视图单元格高度是可变的。没有一个解决方案让我满意(最后一个 tableview 行不可见或仅部分可见)。但是,这对我有用:

在 Interface Builder (IB) 中,将单元格的行高设置为大于我预期的平均行高(在我的情况下为 50)(确保选中“自定义”复选框)。

在实现tableview的ViewController的'viewDidLoad'函数中设置tableview的'rowHeight'属性如下:

myTableView.rowHeight = UITableViewAutomaticDimension

此外,在“viewDidLoad”函数中,将 tableview 的“estimatedRowHeight”设置为高于您预期的平均行高的值。在我的情况下是 140。

最后也是最重要的是我写了这段代码:

extension UITableView 

    func scrollToBottom() 
        let rows = self.numberOfRows(inSection: 0)

        let indexPath = IndexPath(row: rows - 1, section: 0)
        self.scrollToRow(at: indexPath, at: .top, animated: true)
    

注意at: .top — 这就是解决我的问题的方法。为UITableViewScrollPosition 参数传递.bottom 值不起作用。即使通过 .middle 也有效——但不是 .bottom

所以,每当我的数据集需要更新或有新消息到达时,我都会致电

func getTableViewData()
    // Get your data here any way you usually do..

    // call to reload
    myTableView.reloadData()
    // call the scroll function
    myTableView.scrollToBottom()

我通过简单地将at: .bottom 参数更改为at: .top 来测试这个“方法”的结果。每次我将其更改为 at: .top 时,最后一个表格行都是完全可见的,并且表格一直滚动到底部。

【讨论】:

确实——.top.bottom 更适合滚动到底部。惊人的发现! 惊人的发现!数周以来,我一直在寻找解决此问题的有效解决方案,.top 完美运行! 这在性能方面有多好?到目前为止,所有使用scrollToRow 进行可变高度行的尝试都太糟糕了。我说的是快速随机出现的行。 我没有性能问题。我的TableView 相当简单。如果我有图片,它们会在后台线程上加载。【参考方案2】:

最终,我找到了答案。滚动到底部不起作用(插入/删除行也有问题,我稍后发现)的原因是单元格高度为not properly estimated。为了解决这个问题,请尝试在estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath 中返回接近的估计值。但是,如果您不能这样做(并且在大多数情况下您将无法做到),仍然有一个很好的解决方案:将单元格的高度存储在字典中,并在单元格为 estimatedHeight 时返回这些高度重用(例如滚动表格视图)。我在另一个问题中找到了这个解决方案,所以请去看看你将如何执行此操作的实际代码。 (虽然可能,你们中的许多人都可以自己写)

Original solution by @dosdos

编辑:也许修复只是滚动到底部这是不必要的,但在我看来强烈推荐。如果您不使用它来估计行高,您将遇到其他问题,例如滚动错误和大量单元格的性能变差。

您还需要将此添加到viewDidAppear

let lastItem = IndexPath(item: dataSource.count - 1, section: 0)
tableView.scrollToRow(at: lastItem, at: .bottom, animated: true)

【讨论】:

【参考方案3】:

希望这对您有用。试试这个

[self.tableview setContentOffset:CGPointMake(0, CGFLOAT_MAX)]

或者

if (self.tableview.contentSize.height > self.tableview.frame.size.height) 
    
        CGPoint offset = CGPointMake(0, self.tableview.contentSize.height -     self.tableview.frame.size.height);
        [self.tableview setContentOffset:offset animated:YES];
    

【讨论】:

我得到了其他解决方案,但使用 CGFloat.greatestFiniteMagnitude(CGFLOAT_MAX 的快速版本)实际上是最有效的,因为它导致表视图只调用 cellForRow(at: IndexPath, ...)最底层的细胞。谢谢!【参考方案4】:

尝试使用 scrollToRowAtIndexPath,如下面的代码所述。

- (void)viewWillAppear:(BOOL)animated 


    [super viewWillAppear:animated];

    NSInteger no = array.count-1;

    NSIndexPath *lastIndex = [NSIndexPath indexPathForRow:no inSection:0];

   [self.tableView scrollToRowAtIndexPath:lastIndex atScrollPosition:UITableViewScrollPositionBottom animated:YES];


【讨论】:

欢迎您,祝您编码愉快。【参考方案5】:

我可以通过以下简单的步骤来完成它:

1) 在 IB 中手动将估计高度设置为高于预期的值 2)在viewWillAppear中滚动到最后一行,ScrollPosition参数为UITableViewScrollPositionTop

【讨论】:

以上是关于使用动态单元格高度时将表格视图滚动到底部的主要内容,如果未能解决你的问题,请参考以下文章

如何让 UITableView 在动态高度单元格中滚动到底部?

重新加载单元格高度变化的单元格时,UITableView 滚动到顶部

设置表格视图单元格的动态高度

加载视图控制器时如何滚动到特定的 UITableViewCell 顶部到 UITableView 顶部

如何从动态 UITableView 单元格中获取 UILabel 的大小?

UITableview 单元格高度在 iOS 14.0 中的滚动表视图上发生变化