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

7

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

不知何故,在这种情况下,以下代码无法正常工作:

[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:...] 有效吗? - J.Hunter
不好意思,没有... - Balázs Vincze
1
尝试使用tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: arrayData.count, inSection: 0), atScrollPosition: UITableViewScrollPosition.Bottom, animated: true)方法。 - Bharat Modi
你能具体说明一下它不起作用的情况吗? - Bhadresh Mulsaniya
尝试一下这个,如果 (arrayData.count) { NSIndexPath *indexPath = [NSIndexPath indexPathForRow:arrayData.count - 1 inSection:0]; [self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionNone]; [self tableView:self.tableView didSelectRowAtIndexPath:indexPath]; } - Ravindhiran
更好的解决方案请参考:https://dev59.com/YVsX5IYBdhLWcg3whv3Q#54122856 希望这能帮到你。 - Jayraj Vala
5个回答

9
以下是适用于我的Swift 3.1代码的解决方法,使用Xcode 8.3.2针对仅iPhone的iOS 10.1。 我遇到了与OP相同的问题。 我的应用程序包括消息功能。 当消息视图被推入堆栈时,我希望最后一篇帖子可见。 由于消息内容的不同,我的表格视图单元格高度是可变的。 没有任何解决方案能够满足我的要求(最后一个表格视图行不可见或仅部分可见)。 但是,这是对我有效的解决方法:
  • In the Interface Builder (IB) set the cell Row Height to a value greater than I expected my average row height to be in my case 50 (make sure to check the 'Custom' checkbox).
  • In the ViewController where the tableview is implemented inside the 'viewDidLoad' function set the tableview's 'rowHeight' property as follows:

    myTableView.rowHeight = UITableViewAutomaticDimension
    
  • Also in the 'viewDidLoad' function set the tableview's 'estimatedRowHeight' to a value higher than you expect your average row height to be. In my case 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这一行——这是解决我的问题的关键。将.bottom值传递给UITableViewScrollPosition参数根本不起作用。即使传递.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更适合滚动到底部。惊人的发现! - villapossu
太棒了!我已经寻找解决这个问题的可行方案好几周了,而.top无瑕地运作! - Jeff Jones
从性能方面来说,这个有多好?到目前为止,对于可变高度行的所有scrollToRow尝试都太糟糕了。我指的是以快速且随机的方式出现的许多行。 - Jonny
我没有性能问题。我的TableView相当简单。如果有图片,它们会在后台线程上加载。 - Barns

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

原始解决方案由@dosdos提供

编辑:也许只需修复滚动到底部即可,但在我看来强烈建议这样做。如果您不使用它来估算行高度,您将遇到其他问题,比如在大量单元格上出现故障滚动和更糟糕的性能。

另外,你需要将这个添加到viewDidAppear中。

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

1
希望这对您有用。请尝试这个。
[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];
    }

1
我找到了其他的解决方案,但是使用 CGFloat.greatestFiniteMagnitude(CGFLOAT_MAX的Swift版本)实际上是最有效的,因为它只会让表视图为底部单元格调用 cellForRow(at: IndexPath, ...)。谢谢! - Cameron Askew

0

我通过以下简单步骤使其工作:

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


0

尝试使用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];

}

欢迎,祝你编程愉快。 - Hasya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接