如何在UITableView出现之前滚动到iPhone的底部

时间:2022-08-25 07:43:33

I have a UITableView that is populated with cells of a variable height. I would like the table to scroll to the bottom when the view is pushed into view.

我有一个UITableView,它是由可变高度的单元格填充的。当视图被推入视图时,我希望该表滚动到底部。

I currently have the following function

我目前有以下功能

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[log count]-1 inSection:0];
[self.table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];

log is a mutable array containing the objects that make up the content of each cell.

log是一个包含组成每个单元格内容的对象的可变数组。

The above code works fine in viewDidAppear however this has the unfortunate side effect of displaying the top of the table when the view first appears and then jumping to the bottom. I would prefer it if the table view could be scrolled to the bottom before it appears.

上面的代码在viewDidAppear中运行良好,但是这有一个不幸的副作用,当视图第一次出现时显示表的顶部,然后跳到底部。如果表视图在出现之前可以滚动到底部,我将更喜欢它。

I tried the scroll in viewWillAppear and viewDidLoad but in both cases the data has not been loaded into the table yet and both throw an exception.

我尝试了viewWillAppear和viewDidLoad中的滚动,但在这两种情况下,数据还没有加载到表中,两者都抛出一个异常。

Any guidance would be much appreciated, even if it's just a case of telling me what I have is all that is possible.

任何指导都将非常感谢,即使只是告诉我我所拥有的一切都是可能的。

30 个解决方案

#1


139  

I believe that calling [table setContentOffset:CGPointMake(0, CGFLOAT_MAX)] will do what you want.

我相信调用[table setContentOffset:CGPointMake(0, CGFLOAT_MAX)]将完成您想要的工作。

#2


118  

From Jacob's answer, this is the code:

雅各布的回答是:

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

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

#3


113  

I think the easiest way is this:

我认为最简单的方法是

if (self.messages.count > 0)
{
    [self.tableView 
        scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.messages.count-1 
        inSection:0] 
        atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

Swift 3 Version:

斯威夫特3版本:

if messages.count > 0 {
    userDefinedOptionsTableView.scrollToRow(at: IndexPath(item:messages.count-1, section: 0), at: .bottom, animated: true)
}

#4


40  

If you need to scroll to the EXACT end of the content, you can do it like this:

如果你需要滚动到内容的最后,你可以这样做:

- (void)scrollToBottom
{
    CGFloat yOffset = 0;

    if (self.tableView.contentSize.height > self.tableView.bounds.size.height) {
        yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height;
    }

    [self.tableView setContentOffset:CGPointMake(0, yOffset) animated:NO];
}

#5


30  

I'm using autolayout and none of the answers worked for me. Here is my solution that finally worked:

我在使用自动布局,没有一个答案对我有效。以下是我最终奏效的解决方案:

@property (nonatomic, assign) BOOL shouldScrollToLastRow;


- (void)viewDidLoad {
    [super viewDidLoad];

    _shouldScrollToLastRow = YES;
}


- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    // Scroll table view to the last row
    if (_shouldScrollToLastRow)
    {
        _shouldScrollToLastRow = NO;
        [self.tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
    }
}

#6


22  

The accepted solution by @JacobRelkin didn't work for me in iOS 7.0 using Auto Layout.

@JacobRelkin所接受的解决方案在使用自动布局的iOS 7.0中对我不起作用。

I have a custom subclass of UIViewController and added an instance variable _tableView as a subview of its view. I positioned _tableView using Auto Layout. I tried calling this method at the end of viewDidLoad and even in viewWillAppear:. Neither worked.

我有一个UIViewController的自定义子类并添加了一个实例变量_tableView作为其视图的子视图。我使用自动布局定位_tableView。我尝试在viewDidLoad末尾调用这个方法,甚至在viewWillAppear:。既不工作。

So, I added the following method to my custom subclass of UIViewController.

因此,我将下面的方法添加到UIViewController的自定义子类中。

- (void)tableViewScrollToBottomAnimated:(BOOL)animated {
    NSInteger numberOfRows = [_tableView numberOfRowsInSection:0];
    if (numberOfRows) {
        [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:numberOfRows-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:animated];
    }
}

Calling [self tableViewScrollToBottomAnimated:NO] at the end of viewDidLoad works. Unfortunately, it also causes tableView:heightForRowAtIndexPath: to get called three times for every cell.

在viewDidLoad工作结束时调用[self tableViewScrollToBottomAnimated:NO]。不幸的是,它还导致tableView:heightForRowAtIndexPath:对每个单元格调用三次。

#7


20  

Here's an extension that I implemented in Swift 2.0. These functions should be called after the tableview has been loaded:

这是我在Swift 2.0中实现的扩展。这些函数应该在加载tableview后调用:

import UIKit

extension UITableView {
    func setOffsetToBottom(animated: Bool) {
        self.setContentOffset(CGPointMake(0, self.contentSize.height - self.frame.size.height), animated: true)
    }

    func scrollToLastRow(animated: Bool) {
        if self.numberOfRowsInSection(0) > 0 {
            self.scrollToRowAtIndexPath(NSIndexPath(forRow: self.numberOfRowsInSection(0) - 1, inSection: 0), atScrollPosition: .Bottom, animated: animated)
        }
    }
}

#8


12  

Details

xCode 8.3.2, swift 3.1

xCode 8.3.2,斯威夫特3.1

Code

import UIKit

extension UITableView {
    func scrollToBottom(animated: Bool) {
        let y = contentSize.height - frame.size.height
        setContentOffset(CGPoint(x: 0, y: (y<0) ? 0 : y), animated: animated)
    }
}

Usage

tableView.scrollToBottom(animated: true)

#9


10  

Actually a "Swifter" way to do it in swift is :

实际上,在swift中,一种“更快”的方式是:

var lastIndex = NSIndexPath(forRow: self.messages.count - 1, inSection: 0)
            self.messageTableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Bottom, animated: true)

work Perfect for me.

工作适合我。

#10


9  

I wanted the table to load with the end of the table shown in the frame. I found using

我想让这个表加载框架中显示的这个表的末尾。我发现使用

NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0];
[[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];

did not work because it gave an error when table height was less than the frame height. Note my table only has one section.

没有工作,因为它给出了一个错误,当表高度小于框架高度。注意,我的表只有一个部分。

The solution that worked for me was implement the following code in viewWillAppear:

我的解决方案是在viewWillAppear中实现以下代码:

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// on the initial cell load scroll to the last row (ie the latest Note)
if (initialLoad==TRUE) {
    initialLoad=FALSE; 
    NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0];
    [[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
        CGPoint offset = CGPointMake(0, (1000000.0));
        [self.tableView setContentOffset:offset animated:NO];
    }
}

The BOOL ivar initialLoad is set to TRUE in viewDidLoad.

在viewDidLoad中,BOOL ivar initialLoad设置为TRUE。

#11


7  

For Swift:

迅速:

if tableView.contentSize.height > tableView.frame.size.height
        {
            let offset = CGPoint(x: 0, y: tableView.contentSize.height - tableView.frame.size.height)
            tableView.setContentOffset(offset, animated: false)
        }

#12


5  

You should use UITableViewScrollPositionBottom instead.

您应该使用UITableViewScrollPositionBottom代替。

#13


4  

Is of course a Bug. Probably somewhere in your code you use table.estimatedRowHeight = value (for example 100). Replace this value by the highest value you think a row height could get, for example 500.. This should solve the problem in combination with following code:

当然是一个Bug。可能在您的代码中,您使用了表。estimatedrowh8 =值(例如100)。将这个值替换为您认为行高可以得到的最高值,例如500。这应该结合以下代码来解决问题:

//auto scroll down example
let delay = 0.1 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

dispatch_after(time, dispatch_get_main_queue(), {
    self.table.scrollToRowAtIndexPath(NSIndexPath(forRow: self.Messages.count - 1, inSection: 0), atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
})

#14


4  

For Swift 3 ( Xcode 8.1 ):

Swift 3 (Xcode 8.1):

override func viewDidAppear(_ animated: Bool) {
    let numberOfSections = self.tableView.numberOfSections
    let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)

    let indexPath = IndexPath(row: numberOfRows-1 , section: numberOfSections-1)
    self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.middle, animated: true)
}

#15


3  

Using the above solutions, this will scroll to the bottom of your table (only if the table content is loaded first):

使用上述解决方案,这将滚动到表的底部(只有在首先加载表内容时):

//Scroll to bottom of table
CGSize tableSize = myTableView.contentSize;
[myTableView setContentOffset:CGPointMake(0, tableSize.height)];

#16


3  

After a lot of fiddling this is what worked for me:

经过大量的摆弄之后,这对我起了作用:

var viewHasAppeared = false

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if !viewHasAppeared { goToBottom() }
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    viewHasAppeared = true
}

private func goToBottom() {
    guard data.count > 0 else { return }
    let indexPath = NSIndexPath(forRow: data.count - 1, inSection: 0)
    tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: false)
    tableView.layoutIfNeeded()
}

The key turned out to be not wrapping scrollToRowAtIndexPath inside of dispatch_async as some have suggested, but simply following it with a call to layoutIfNeeded.

结果发现,关键不像一些人建议的那样,将scrollToRowAtIndexPath封装在dispatch_async中,而仅仅是在调用layoutifneed之后。

My understanding of this is, calling the scroll method in the current thread guarantees that the scroll offset is set immediately, before the view is displayed. When I was dispatching to the main thread, the view was getting displayed for an instant before the scroll took effect.

我的理解是,在当前线程中调用滚动方法可以保证在显示视图之前立即设置滚动偏移量。当我调度到主线程时,视图在滚动生效之前显示了一会儿。

(Also NB you need the viewHasAppeared flag because you don't want to goToBottom every time viewDidLayoutSubviews is called. It gets called for example whenever the orientation changes.)

(同样,NB需要viewhasappear标志,因为您不希望每次调用viewDidLayoutSubviews时都访问底部。例如,当方向改变时,它就会被调用)

#17


3  

In Swift 3.0

在斯威夫特3.0

self.tableViewFeeds.setContentOffset(CGPoint(x: 0, y: CGFLOAT_MAX), animated: true)

#18


2  

Thanks Jacob for the answer. really helpfull if anyone interesting with monotouch c# version

谢谢雅各布的回答。如果有人对monotouch c#版本感兴趣的话,这真的很有帮助

private void SetScrollPositionDown()
    {
        if (tblShoppingListItem.ContentSize.Height > tblShoppingListItem.Frame.Size.Height)
        {
            PointF offset = new PointF(0,
                                       tblShoppingListItem.ContentSize.Height -
                                       tblShoppingListItem.Frame.Size.Height);
            tblShoppingListItem.SetContentOffset(offset,true );
        }

    }

#19


2  

Use this simple code to scroll tableView bottom

使用这个简单的代码滚动tableView底部

NSInteger rows = [tableName numberOfRowsInSection:0];
            if(rows > 0) {

                [tableName scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rows-1 inSection:0]
                                 atScrollPosition:UITableViewScrollPositionBottom
                                         animated:YES];
            }

#20


2  

If you have to load the data asynchronously prior to scrolling down, here's the possible solution:

如果在向下滚动之前必须异步加载数据,可能的解决方案是:

tableView.alpha = 0 // We want animation!
lastMessageShown = false // This is ivar

viewModel.fetch { [unowned self] result in
    self.tableView.reloadData()

    if !self.lastMessageShown {
        dispatch_async(dispatch_get_main_queue()) { [unowned self] in
            if self.rowCount > 0 {
                self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: self.rowCount, inSection: 0), atScrollPosition: .Bottom, animated: false)
            }

            UIView.animateWithDuration(0.1) {
                self.tableView.alpha = 1
                self.lastMessageShown = true // Do it once
            }
        }
    }
}

#21


2  

Function on swift 3 scroll to bottom

功能在swift 3滚动到底部。

 override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(false)
        //scroll down
        if lists.count > 2 {
            let numberOfSections = self.tableView.numberOfSections
            let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
            let indexPath = IndexPath(row: numberOfRows-1 , section: numberOfSections-1)
            self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.middle, animated: true)
        }
    }

#22


1  

In iOS this worked fine for me

在iOS中,这对我来说很好

CGFloat height = self.inputTableView.contentSize.height;
if (height > CGRectGetHeight(self.inputTableView.frame)) {
    height -= (CGRectGetHeight(self.inputTableView.frame) - CGRectGetHeight(self.navigationController.navigationBar.frame));
}
else {
    height = 0;
}
[self.inputTableView setContentOffset:CGPointMake(0, height) animated:animated];

It needs to be called from viewDidLayoutSubviews

它需要从viewDidLayoutSubviews调用。

#23


1  

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

(自我。tableViewInfo scrollRectToVisible:CGRectMake(0,self.tableViewInfo.contentSize.height-self.tableViewInfo。高度,self.tableViewInfo。宽度,self.tableViewInfo.height)动画:是的);

#24


1  

The accepted answer didn't work with my table (thousands of rows, dynamic loading) but the code below works:

接受的答案对我的表(数千行,动态加载)不起作用,但是下面的代码可以工作:

- (void)scrollToBottom:(id)sender {
    if ([self.sections count] > 0) {
        NSInteger idx = [self.sections count] - 1;
        CGRect sectionRect = [self.tableView rectForSection:idx];
        sectionRect.size.height = self.tableView.frame.size.height;
        [self.tableView scrollRectToVisible:sectionRect animated:NO];
    }
}

#25


1  

No need for any scrolling you can just do it by using this code:

无需滚动,只需使用以下代码即可:

[YOURTABLEVIEWNAME setContentOffset:CGPointMake(0, CGFLOAT_MAX)];

#26


1  

If you are setting up frame for tableview programmatically, make sure you are setting frame correctly.

如果您正在以编程方式为tableview设置框架,请确保您正在正确地设置框架。

#27


1  

func scrollToBottom() {

    let sections = self.chatTableView.numberOfSections

    if sections > 0 {

        let rows = self.chatTableView.numberOfRows(inSection: sections - 1)

        let last = IndexPath(row: rows - 1, section: sections - 1)

        DispatchQueue.main.async {

            self.chatTableView.scrollToRow(at: last, at: .bottom, animated: false)
        }
    }
}

you should add

你应该添加

DispatchQueue.main.async {
            self.chatTableView.scrollToRow(at: last, at: .bottom, animated: false)
        }

or it will not scroll to bottom.

或者它不会滚动到底部。

#28


0  

In Swift, you just need

在Swift中,你只需要

self.tableView.scrollToNearestSelectedRowAtScrollPosition(UITableViewScrollPosition.Bottom, animated: true)

to make it automatically scroll to the buttom

使它自动滚动到按钮

#29


0  

In swift 3.0 If you want to go any particular Cell of tableview Change cell index Value like change "self.yourArr.count" value .

在swift 3.0中,如果你想去任何特定的单元格,你可以改变单元格的索引值,比如“self。yourarr”。”价值。

self.yourTable.reloadData()
self.scrollToBottom() 
func scrollToBottom(){
    DispatchQueue.global(qos: .background).async {
        let indexPath = IndexPath(row: self.yourArr.count-1, section: 0)
        self.tblComment.scrollToRow(at: indexPath, at: .bottom, animated: true)
    }
}

#30


0  

I believe old solutions do not work with swift3.

我认为旧的解决方案不适合swift3。

If you know number rows in table you can use :

如果你知道表格中的数字行,你可以使用:

tableView.scrollToRow(
    at: IndexPath(item: listCountInSection-1, section: sectionCount - 1 ), 
    at: .top, 
    animated: true)

#1


139  

I believe that calling [table setContentOffset:CGPointMake(0, CGFLOAT_MAX)] will do what you want.

我相信调用[table setContentOffset:CGPointMake(0, CGFLOAT_MAX)]将完成您想要的工作。

#2


118  

From Jacob's answer, this is the code:

雅各布的回答是:

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

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

#3


113  

I think the easiest way is this:

我认为最简单的方法是

if (self.messages.count > 0)
{
    [self.tableView 
        scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.messages.count-1 
        inSection:0] 
        atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

Swift 3 Version:

斯威夫特3版本:

if messages.count > 0 {
    userDefinedOptionsTableView.scrollToRow(at: IndexPath(item:messages.count-1, section: 0), at: .bottom, animated: true)
}

#4


40  

If you need to scroll to the EXACT end of the content, you can do it like this:

如果你需要滚动到内容的最后,你可以这样做:

- (void)scrollToBottom
{
    CGFloat yOffset = 0;

    if (self.tableView.contentSize.height > self.tableView.bounds.size.height) {
        yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height;
    }

    [self.tableView setContentOffset:CGPointMake(0, yOffset) animated:NO];
}

#5


30  

I'm using autolayout and none of the answers worked for me. Here is my solution that finally worked:

我在使用自动布局,没有一个答案对我有效。以下是我最终奏效的解决方案:

@property (nonatomic, assign) BOOL shouldScrollToLastRow;


- (void)viewDidLoad {
    [super viewDidLoad];

    _shouldScrollToLastRow = YES;
}


- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    // Scroll table view to the last row
    if (_shouldScrollToLastRow)
    {
        _shouldScrollToLastRow = NO;
        [self.tableView setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
    }
}

#6


22  

The accepted solution by @JacobRelkin didn't work for me in iOS 7.0 using Auto Layout.

@JacobRelkin所接受的解决方案在使用自动布局的iOS 7.0中对我不起作用。

I have a custom subclass of UIViewController and added an instance variable _tableView as a subview of its view. I positioned _tableView using Auto Layout. I tried calling this method at the end of viewDidLoad and even in viewWillAppear:. Neither worked.

我有一个UIViewController的自定义子类并添加了一个实例变量_tableView作为其视图的子视图。我使用自动布局定位_tableView。我尝试在viewDidLoad末尾调用这个方法,甚至在viewWillAppear:。既不工作。

So, I added the following method to my custom subclass of UIViewController.

因此,我将下面的方法添加到UIViewController的自定义子类中。

- (void)tableViewScrollToBottomAnimated:(BOOL)animated {
    NSInteger numberOfRows = [_tableView numberOfRowsInSection:0];
    if (numberOfRows) {
        [_tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:numberOfRows-1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:animated];
    }
}

Calling [self tableViewScrollToBottomAnimated:NO] at the end of viewDidLoad works. Unfortunately, it also causes tableView:heightForRowAtIndexPath: to get called three times for every cell.

在viewDidLoad工作结束时调用[self tableViewScrollToBottomAnimated:NO]。不幸的是,它还导致tableView:heightForRowAtIndexPath:对每个单元格调用三次。

#7


20  

Here's an extension that I implemented in Swift 2.0. These functions should be called after the tableview has been loaded:

这是我在Swift 2.0中实现的扩展。这些函数应该在加载tableview后调用:

import UIKit

extension UITableView {
    func setOffsetToBottom(animated: Bool) {
        self.setContentOffset(CGPointMake(0, self.contentSize.height - self.frame.size.height), animated: true)
    }

    func scrollToLastRow(animated: Bool) {
        if self.numberOfRowsInSection(0) > 0 {
            self.scrollToRowAtIndexPath(NSIndexPath(forRow: self.numberOfRowsInSection(0) - 1, inSection: 0), atScrollPosition: .Bottom, animated: animated)
        }
    }
}

#8


12  

Details

xCode 8.3.2, swift 3.1

xCode 8.3.2,斯威夫特3.1

Code

import UIKit

extension UITableView {
    func scrollToBottom(animated: Bool) {
        let y = contentSize.height - frame.size.height
        setContentOffset(CGPoint(x: 0, y: (y<0) ? 0 : y), animated: animated)
    }
}

Usage

tableView.scrollToBottom(animated: true)

#9


10  

Actually a "Swifter" way to do it in swift is :

实际上,在swift中,一种“更快”的方式是:

var lastIndex = NSIndexPath(forRow: self.messages.count - 1, inSection: 0)
            self.messageTableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Bottom, animated: true)

work Perfect for me.

工作适合我。

#10


9  

I wanted the table to load with the end of the table shown in the frame. I found using

我想让这个表加载框架中显示的这个表的末尾。我发现使用

NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0];
[[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];

did not work because it gave an error when table height was less than the frame height. Note my table only has one section.

没有工作,因为它给出了一个错误,当表高度小于框架高度。注意,我的表只有一个部分。

The solution that worked for me was implement the following code in viewWillAppear:

我的解决方案是在viewWillAppear中实现以下代码:

- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// on the initial cell load scroll to the last row (ie the latest Note)
if (initialLoad==TRUE) {
    initialLoad=FALSE; 
    NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([self.tableView numberOfRowsInSection:0] - 1) inSection:0];
    [[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
        CGPoint offset = CGPointMake(0, (1000000.0));
        [self.tableView setContentOffset:offset animated:NO];
    }
}

The BOOL ivar initialLoad is set to TRUE in viewDidLoad.

在viewDidLoad中,BOOL ivar initialLoad设置为TRUE。

#11


7  

For Swift:

迅速:

if tableView.contentSize.height > tableView.frame.size.height
        {
            let offset = CGPoint(x: 0, y: tableView.contentSize.height - tableView.frame.size.height)
            tableView.setContentOffset(offset, animated: false)
        }

#12


5  

You should use UITableViewScrollPositionBottom instead.

您应该使用UITableViewScrollPositionBottom代替。

#13


4  

Is of course a Bug. Probably somewhere in your code you use table.estimatedRowHeight = value (for example 100). Replace this value by the highest value you think a row height could get, for example 500.. This should solve the problem in combination with following code:

当然是一个Bug。可能在您的代码中,您使用了表。estimatedrowh8 =值(例如100)。将这个值替换为您认为行高可以得到的最高值,例如500。这应该结合以下代码来解决问题:

//auto scroll down example
let delay = 0.1 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

dispatch_after(time, dispatch_get_main_queue(), {
    self.table.scrollToRowAtIndexPath(NSIndexPath(forRow: self.Messages.count - 1, inSection: 0), atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
})

#14


4  

For Swift 3 ( Xcode 8.1 ):

Swift 3 (Xcode 8.1):

override func viewDidAppear(_ animated: Bool) {
    let numberOfSections = self.tableView.numberOfSections
    let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)

    let indexPath = IndexPath(row: numberOfRows-1 , section: numberOfSections-1)
    self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.middle, animated: true)
}

#15


3  

Using the above solutions, this will scroll to the bottom of your table (only if the table content is loaded first):

使用上述解决方案,这将滚动到表的底部(只有在首先加载表内容时):

//Scroll to bottom of table
CGSize tableSize = myTableView.contentSize;
[myTableView setContentOffset:CGPointMake(0, tableSize.height)];

#16


3  

After a lot of fiddling this is what worked for me:

经过大量的摆弄之后,这对我起了作用:

var viewHasAppeared = false

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    if !viewHasAppeared { goToBottom() }
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    viewHasAppeared = true
}

private func goToBottom() {
    guard data.count > 0 else { return }
    let indexPath = NSIndexPath(forRow: data.count - 1, inSection: 0)
    tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: false)
    tableView.layoutIfNeeded()
}

The key turned out to be not wrapping scrollToRowAtIndexPath inside of dispatch_async as some have suggested, but simply following it with a call to layoutIfNeeded.

结果发现,关键不像一些人建议的那样,将scrollToRowAtIndexPath封装在dispatch_async中,而仅仅是在调用layoutifneed之后。

My understanding of this is, calling the scroll method in the current thread guarantees that the scroll offset is set immediately, before the view is displayed. When I was dispatching to the main thread, the view was getting displayed for an instant before the scroll took effect.

我的理解是,在当前线程中调用滚动方法可以保证在显示视图之前立即设置滚动偏移量。当我调度到主线程时,视图在滚动生效之前显示了一会儿。

(Also NB you need the viewHasAppeared flag because you don't want to goToBottom every time viewDidLayoutSubviews is called. It gets called for example whenever the orientation changes.)

(同样,NB需要viewhasappear标志,因为您不希望每次调用viewDidLayoutSubviews时都访问底部。例如,当方向改变时,它就会被调用)

#17


3  

In Swift 3.0

在斯威夫特3.0

self.tableViewFeeds.setContentOffset(CGPoint(x: 0, y: CGFLOAT_MAX), animated: true)

#18


2  

Thanks Jacob for the answer. really helpfull if anyone interesting with monotouch c# version

谢谢雅各布的回答。如果有人对monotouch c#版本感兴趣的话,这真的很有帮助

private void SetScrollPositionDown()
    {
        if (tblShoppingListItem.ContentSize.Height > tblShoppingListItem.Frame.Size.Height)
        {
            PointF offset = new PointF(0,
                                       tblShoppingListItem.ContentSize.Height -
                                       tblShoppingListItem.Frame.Size.Height);
            tblShoppingListItem.SetContentOffset(offset,true );
        }

    }

#19


2  

Use this simple code to scroll tableView bottom

使用这个简单的代码滚动tableView底部

NSInteger rows = [tableName numberOfRowsInSection:0];
            if(rows > 0) {

                [tableName scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rows-1 inSection:0]
                                 atScrollPosition:UITableViewScrollPositionBottom
                                         animated:YES];
            }

#20


2  

If you have to load the data asynchronously prior to scrolling down, here's the possible solution:

如果在向下滚动之前必须异步加载数据,可能的解决方案是:

tableView.alpha = 0 // We want animation!
lastMessageShown = false // This is ivar

viewModel.fetch { [unowned self] result in
    self.tableView.reloadData()

    if !self.lastMessageShown {
        dispatch_async(dispatch_get_main_queue()) { [unowned self] in
            if self.rowCount > 0 {
                self.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: self.rowCount, inSection: 0), atScrollPosition: .Bottom, animated: false)
            }

            UIView.animateWithDuration(0.1) {
                self.tableView.alpha = 1
                self.lastMessageShown = true // Do it once
            }
        }
    }
}

#21


2  

Function on swift 3 scroll to bottom

功能在swift 3滚动到底部。

 override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(false)
        //scroll down
        if lists.count > 2 {
            let numberOfSections = self.tableView.numberOfSections
            let numberOfRows = self.tableView.numberOfRows(inSection: numberOfSections-1)
            let indexPath = IndexPath(row: numberOfRows-1 , section: numberOfSections-1)
            self.tableView.scrollToRow(at: indexPath, at: UITableViewScrollPosition.middle, animated: true)
        }
    }

#22


1  

In iOS this worked fine for me

在iOS中,这对我来说很好

CGFloat height = self.inputTableView.contentSize.height;
if (height > CGRectGetHeight(self.inputTableView.frame)) {
    height -= (CGRectGetHeight(self.inputTableView.frame) - CGRectGetHeight(self.navigationController.navigationBar.frame));
}
else {
    height = 0;
}
[self.inputTableView setContentOffset:CGPointMake(0, height) animated:animated];

It needs to be called from viewDidLayoutSubviews

它需要从viewDidLayoutSubviews调用。

#23


1  

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

(自我。tableViewInfo scrollRectToVisible:CGRectMake(0,self.tableViewInfo.contentSize.height-self.tableViewInfo。高度,self.tableViewInfo。宽度,self.tableViewInfo.height)动画:是的);

#24


1  

The accepted answer didn't work with my table (thousands of rows, dynamic loading) but the code below works:

接受的答案对我的表(数千行,动态加载)不起作用,但是下面的代码可以工作:

- (void)scrollToBottom:(id)sender {
    if ([self.sections count] > 0) {
        NSInteger idx = [self.sections count] - 1;
        CGRect sectionRect = [self.tableView rectForSection:idx];
        sectionRect.size.height = self.tableView.frame.size.height;
        [self.tableView scrollRectToVisible:sectionRect animated:NO];
    }
}

#25


1  

No need for any scrolling you can just do it by using this code:

无需滚动,只需使用以下代码即可:

[YOURTABLEVIEWNAME setContentOffset:CGPointMake(0, CGFLOAT_MAX)];

#26


1  

If you are setting up frame for tableview programmatically, make sure you are setting frame correctly.

如果您正在以编程方式为tableview设置框架,请确保您正在正确地设置框架。

#27


1  

func scrollToBottom() {

    let sections = self.chatTableView.numberOfSections

    if sections > 0 {

        let rows = self.chatTableView.numberOfRows(inSection: sections - 1)

        let last = IndexPath(row: rows - 1, section: sections - 1)

        DispatchQueue.main.async {

            self.chatTableView.scrollToRow(at: last, at: .bottom, animated: false)
        }
    }
}

you should add

你应该添加

DispatchQueue.main.async {
            self.chatTableView.scrollToRow(at: last, at: .bottom, animated: false)
        }

or it will not scroll to bottom.

或者它不会滚动到底部。

#28


0  

In Swift, you just need

在Swift中,你只需要

self.tableView.scrollToNearestSelectedRowAtScrollPosition(UITableViewScrollPosition.Bottom, animated: true)

to make it automatically scroll to the buttom

使它自动滚动到按钮

#29


0  

In swift 3.0 If you want to go any particular Cell of tableview Change cell index Value like change "self.yourArr.count" value .

在swift 3.0中,如果你想去任何特定的单元格,你可以改变单元格的索引值,比如“self。yourarr”。”价值。

self.yourTable.reloadData()
self.scrollToBottom() 
func scrollToBottom(){
    DispatchQueue.global(qos: .background).async {
        let indexPath = IndexPath(row: self.yourArr.count-1, section: 0)
        self.tblComment.scrollToRow(at: indexPath, at: .bottom, animated: true)
    }
}

#30


0  

I believe old solutions do not work with swift3.

我认为旧的解决方案不适合swift3。

If you know number rows in table you can use :

如果你知道表格中的数字行,你可以使用:

tableView.scrollToRow(
    at: IndexPath(item: listCountInSection-1, section: sectionCount - 1 ), 
    at: .top, 
    animated: true)