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

问题描述 投票:0回答:6

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

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

[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的代码滚动到底部,对于你们中的一些人来说,独自一人就可以做到这一点。

ios objective-c xcode uitableview
6个回答
9
投票

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

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

  • 在 Interface Builder (IB) 中,将单元格行高设置为大于我预期的平均行高的值(在本例中为 50)(确保选中“自定义”复选框)。
  • 在 ViewController 中,在“viewDidLoad”函数中实现 tableview,设置 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
——这就是解决我的问题的方法。为
.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
时,最后的表格行都是完全可见的,并且表格一直滚动到底部。


4
投票

最终,我找到了答案。滚动到底部不起作用的原因(并且插入/删除行也有问题,正如我后来发现的那样),是因为单元格高度为

not properly estimated
。为了解决这个问题,请尝试在
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];
    }

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];

}

0
投票

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

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


0
投票

一种可能的解决方法是延迟滚动。可能意味着用户体验稍慢。建议进行适当的高度计算。

DispatchQueue.main.async {
    let index = self.numberOfRows(inSection: 0)
    if index > 0 {
        let indexPath = IndexPath(row: index-1, section: 0)
        self.scrollToRow(at: indexPath, at: .bottom, animated: animated)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.