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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38044691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 08:58:28  来源:igfitidea点击:

Scroll table view to bottom when using dynamic cell height

iosobjective-cxcodeuitableview

提问by Balázs Vincze

How can I scroll my table view to the bottom when using dynamic cell height?

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

For some reason this code does not work in this scenario:

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

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

Thanks!

谢谢!

EDIT: Use @Hasiya's code to scroll to the bottom, for some of you that alone might do the trick.

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

采纳答案by Balázs Vincze

Eventually, I have found the answer. The reason why scrolling to the bottom does not work (and inserting/deleting rows are buggy as well, as I found out later), is because cell height is not properly estimated. To get around this, try to return close estimations in estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath. However, if you can't do that (and in most cases you won't be able to) there is still a great solution: Store the heights of the cells in a dictionary, and return those for the estimatedHeightwhen cells are reused (e.g. table view is scrolled). I have found this solution in another question, so please go and check that out for the actual code on how you would carry this out. (although probably, many of you can write this for themselves)

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

Original solution by @dosdos

@dosdos 的原始解决方案

EDIT:Maybe to fix just scrolling to the bottom this is unnecessary, however highly recommended in my opinion. If you don't use this for estimating your row height, you will encounter other problems such as buggy scrolling and worse performance at a large number of cells.

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

Also you need to add this to viewDidAppear

您还需要将此添加到 viewDidAppear

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

回答by Barns

The following worked for my Swift 3.1 code using Xcode 8.3.2 targeting iOS 10.1 for iPhone only.

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

I had the same problem as the OP. My app included a messaging function. I wanted the last post to be visible when the message view was pushed onto the stack. My tableview cell heights are variable due to the content of the messages. None of the solutions worked to my satisfaction (the last tableview row was not visible or only partially visible). But, here is what worked for me:

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

  • 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.

  • 在界面生成器 (IB) 中,将单元格行高设置为大于我预期的平均行高在我的情况下为 50 的值(确保选中“自定义”复选框)。
  • 在“viewDidLoad”函数内实现tableview的ViewController中,设置tableview的“rowHeight”属性如下:

    myTableView.rowHeight = UITableViewAutomaticDimension
    
  • 同样在 'viewDidLoad' 函数中,将 tableview 的 'estimatedRowHeight' 设置为高于您预期的平均行高的值。在我的情况下是 140。

Finally and most importantly I wrote this bit of code:

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

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)
    }
}

Notice the at: .top— this is what solved my problem. Passing the .bottomvalue for the UITableViewScrollPositionparameter just didn't work. Even passing .middleworked — but not .bottom.

注意at: .top——这就是解决我的问题的原因。传递参数的.bottom值是UITableViewScrollPosition行不通的。即使通过.middle工作 - 但不是.bottom

So, any time my dataset need to be updated or a new message arrives I call

因此,每当我的数据集需要更新或收到新消息时,我都会调用

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

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

I tested the results of this 'method' by simply changing the at: .bottomparameter to at: .top. Every time I changed it to at: .topthe last table rows were fully visible and the table scrolled all the way to the bottom.

我通过简单地将at: .bottom参数更改为at: .top. 每次我将其更改为at: .top最后一个表格行时,它都完全可见,并且表格一直滚动到底部。

回答by Nikunj Rajyaguru

Hope this may work for you. Try this

希望这对你有用。尝试这个

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

Or

或者

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

回答by Hasya

Try with scrollToRowAtIndexPath, as mentioned in below code.

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

}

回答by Jim75

I get it work by doing this simple steps:

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

1) in IB set the estimate height manually to a higher-then-expected value 2) in viewWillAppear scroll to the last row with the ScrollPosition parameter as UITableViewScrollPositionTop

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