147

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.

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.

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.

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.

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

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
acqu13sce
  • 3,789
  • 4
  • 25
  • 32

35 Answers35

153

I believe that calling

 tableView.setContentOffset(CGPoint(x: 0, y: CGFloat.greatestFiniteMagnitude), animated: false)

will do what you want.

Sourabh Sharma
  • 8,222
  • 5
  • 68
  • 78
Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
  • 14
    That's perfect thank you. I created a CGPoint with a sufficiently high Y value that will make it always display the bottom. Once the view has loaded I can use (self.table.contentSize.height - self.table.frame.size.height) to move to the bottom with the same method – acqu13sce May 05 '10 at 03:19
  • 9
    Though this is perfect answer, as we don't need to do calculation for how many cells, height of tableview etc.. BUT *I would point that we need to call this before reloading the tableview... It won't work if we write this after `[table reloadData];`* – Fahim Parkar Jan 14 '15 at 05:42
  • I tried this solution but discovered that, if you are using a UIRefreshControl, the refresh control will be shown if the table has a lower height than the screen height, even after calling the [endRefreshing] method. – Luis Delgado Jun 14 '15 at 13:54
  • 4
    doesn't work on ios 10-12 - table simply disappear for first time – Vyachaslav Gerchicov Dec 07 '18 at 14:19
  • 4
    Or just scroll to `CGPoint(x: 0, y: tableView.contentSize.height)` ? – Amber K Dec 25 '18 at 10:22
  • 1
    Crashing on iOS 11. – Pedro Paulo Amorim Apr 19 '19 at 11:01
  • 7
    Yikes!!! Makes the table vanish :-o. Best using [self.table scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO]; – Carl Hine Oct 29 '19 at 15:12
  • Not works for me my contentOffset: {0, 1.7976931348623157e+308} after setting this and table show blank – guru Apr 17 '20 at 09:04
128

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:

if messages.count > 0 {
    userDefinedOptionsTableView.scrollToRow(at: IndexPath(item:messages.count-1, section: 0), at: .bottom, animated: true)
}
Mars
  • 2,505
  • 17
  • 26
Chamira Fernando
  • 6,836
  • 3
  • 23
  • 23
  • 3
    It doesn't work if the cell is taller than the UITableView – Olav Gausaker Sep 14 '17 at 13:08
  • 4
    Cell is Taller than UITableView? never heard such a use case. – Chamira Fernando Sep 15 '17 at 21:35
  • @ChamiraFernando this is the easiest way :) – AITAALI_ABDERRAHMANE Dec 15 '17 at 22:15
  • Note that it might make sense to replace the `messages.count` by the already implemented `myTableView.dataSource!.tableView(myTableView, numberOfRowsInSection: 0)`. Yes it's longer, but it might avoid code repetition. You also need to handle the optional `dataSource` (don't force unwrap as in this sample). – Nikolay Suvandzhiev Oct 08 '18 at 11:54
  • @ChamiraFernando I know this question is old, but just because you never saw, it does not mean it doesn't happens. To answer your question, apps like Foursquare may have this situation, where user writes a review. The cell's height is great than the height of the tableview. Its a perfectly fine situation. – Caio Jun 11 '20 at 18:36
121

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];
    }
}
Community
  • 1
  • 1
Osama F Elias
  • 1,544
  • 1
  • 11
  • 10
  • On iOS 11 you should use adjusted table view frame height: `UIEdgeInsetsInsetRect(self.messagesTableView.frame, self.messagesTableView.safeAreaInsets).height` – Slav Dec 03 '17 at 20:45
42

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];
}
gerry3
  • 21,420
  • 9
  • 66
  • 74
Hans One
  • 3,329
  • 27
  • 28
  • 7
    Works with autolayout, BUT it's important to call this method from viewDidLayoutSubviews – Omaty Feb 26 '15 at 09:28
  • Could you please explain why we need to do this: `yOffset = self.tableView.contentSize.height - self.tableView.bounds.size.height; `? Thanks. – Unheilig May 07 '15 at 04:14
  • 3
    @Unheilig If you would scroll to `self.tableView.contentSize.height` the content of the table view may be not visible, because you scroll below the content. Therefore you have to scroll to one "visible table view gap" above the end of the table view. – Hans One May 07 '15 at 09:25
31

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)];
    }
}
Rafał Sroka
  • 39,540
  • 23
  • 113
  • 143
  • 1
    This almost works for me but I get a weird graphical glitch whilst my table data is loading from an external API. In my case do I need to call `setContentOffset` at some other point when the data has been fetched and tableview reloaded? – jmoz Jun 15 '14 at 16:32
  • Try setting the offset in a completion handler of your request. – Rafał Sroka Jun 15 '14 at 22:04
  • 2
    This does not work in ios 10 - simply shows a table with a black background – RunLoop Jul 14 '17 at 13:47
  • 2
    Instead of using `CGFLOAT_MAX` I used `contentSize.height - frame.height + contentInset.bottom` when setting the initial content offset. Using `CGFLOAT_MAX` seemed to mess up for me. – Baza207 Feb 22 '18 at 11:01
24

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

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)
        }
    }
}
Ryan Herubin
  • 621
  • 6
  • 6
  • 3
    This is better than using content size. For Swift3. if self.numberOfRows(inSection: 0) > 0 { self.scrollToRow(at: IndexPath.init(row: self.numberOfRows(inSection: 0)-1, section: 0), at: .bottom, animated: animated) } – Soohwan Park Mar 23 '17 at 23:05
  • if scrollToLastRow this method is not work perfect then just add self.layoutIfNeeded() and it's work perfect !! – Yogesh Patel Mar 04 '19 at 10:48
23

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

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.

So, I added the following method to my custom subclass of 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.

Community
  • 1
  • 1
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
17

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

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

work Perfect for me.

Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
XcodeNOOB
  • 2,135
  • 4
  • 23
  • 29
15

Details

  • Xcode 8.3.2, swift 3.1
  • Xcode 10.2 (10E125), Swift 5

Code

import UIKit

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

Usage

tableView.scrollToBottom(animated: true)

Full sample

Do not forget to paste solution code!

import UIKit

class ViewController: UIViewController {

    private weak var tableView: UITableView?
    private lazy var cellReuseIdentifier = "CellReuseIdentifier"

    override func viewDidLoad() {
        super.viewDidLoad()
        let tableView = UITableView(frame: view.frame)
        view.addSubview(tableView)
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        self.tableView = tableView
        tableView.dataSource = self
        tableView.performBatchUpdates(nil) { [weak self] result in
            if result { self?.tableView?.scrollToBottom(animated: true) }
        }
    }
}

extension ViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 100
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath )
        cell.textLabel?.text = "\(indexPath)"
        return cell
    }
}
Vasily Bodnarchuk
  • 24,482
  • 9
  • 132
  • 127
9

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)
}
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Segev
  • 1,267
  • 16
  • 21
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:

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

T.J.
  • 3,942
  • 2
  • 32
  • 40
  • Do you need to call `scrollToRowAtIndexPath` at all? You're already calling `setContentOffset` afterwards, which might make that first call pointless. – Carlos P Sep 23 '13 at 12:32
5

For 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)
}
Irshad Qureshi
  • 807
  • 18
  • 41
  • 3
    This doesn't answer OP question, this is what was working from the start. Also you should call super.viewDidAppear – streem Sep 19 '17 at 06:01
5

You should use UITableViewScrollPositionBottom instead.

Erphan Rajput
  • 103
  • 1
  • 8
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:

//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)
})
Machavity
  • 30,841
  • 27
  • 92
  • 100
4

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.

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

skot
  • 428
  • 5
  • 10
4
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.

4

In one line:

tableView.scrollToRow(at: IndexPath(row: data.count - 1, section: 0), at: .bottom, animated: true)

This code is IMHO more clear than the accepted answer.

Mike Keskinov
  • 11,614
  • 6
  • 59
  • 87
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)];
JimmyJammed
  • 9,598
  • 19
  • 79
  • 146
3

Use this simple code to scroll tableView bottom

NSInteger rows = [tableName numberOfRowsInSection:0];
if(rows > 0) {
    [tableName scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rows-1 inSection:0]
                     atScrollPosition:UITableViewScrollPositionBottom
                             animated:YES];
}
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Bibin Joseph
  • 234
  • 2
  • 7
  • 1
    This is basically what the OP said he already tried. This answer does not address the OP's question of how to get it to work properly in viewWillAppear. – jk7 Nov 18 '16 at 17:25
3

In Swift 3.0

self.tableViewFeeds.setContentOffset(CGPoint(x: 0, y: CGFLOAT_MAX), animated: true)
Matthew Verstraete
  • 6,335
  • 22
  • 67
  • 123
Amit Verma
  • 1,393
  • 1
  • 8
  • 7
2

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

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 );
    }
}
Olcay Ertaş
  • 5,987
  • 8
  • 76
  • 112
Mahesh
  • 2,731
  • 2
  • 32
  • 31
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
            }
        }
    }
}
SoftDesigner
  • 5,640
  • 3
  • 58
  • 47
2

Function on swift 3 scroll to bottom

 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)
        }
    }
Tarik
  • 539
  • 7
  • 16
1

In iOS this worked fine for me

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

Eran Goldin
  • 980
  • 12
  • 21
Josip B.
  • 2,434
  • 1
  • 25
  • 30
1

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

leetvin
  • 21
  • 2
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];
    }
}
user3246173
  • 488
  • 6
  • 18
1

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

[YOURTABLEVIEWNAME setContentOffset:CGPointMake(0, CGFLOAT_MAX)];
Paul Roub
  • 36,322
  • 27
  • 84
  • 93
Anuj Kumar Rai
  • 666
  • 1
  • 6
  • 17
1

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

Narasimha Nallamsetty
  • 1,215
  • 14
  • 16
1

On iOS 12 the accepted answer seems to be broken. I had it working with the following extension



import UIKit

extension UITableView {
    public func scrollToBottom(animated: Bool = true) {
        guard let dataSource = dataSource else {
            return
        }

        let sections = dataSource.numberOfSections?(in: self) ?? 1
        let rows = dataSource.tableView(self, numberOfRowsInSection: sections-1)
        let bottomIndex = IndexPath(item: rows - 1, section: sections - 1)

        scrollToRow(at: bottomIndex,
                    at: .bottom,
                    animated: animated)
    }
}
gkaimakas
  • 574
  • 3
  • 17
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 .

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)
    }
}
Amit Verma
  • 1,393
  • 1
  • 8
  • 7
0

I believe old solutions do not work with 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)
ymutlu
  • 6,585
  • 4
  • 35
  • 47
0

I found another good way, as follows:

func yourFunc() {
    //tableView.reloadData()
    self.perform(#selector(scrollToBottom), with: nil, afterDelay: 0.1)
}

@objc func scrollToBottom() {
    self.tableView.scrollToRow(at: IndexPath(row: 0, section: self.mesArr.count - 1), at: .bottom, animated: false)
}
RateRebriduo
  • 265
  • 3
  • 11
0

The safest way to scroll at the bottom of tableView is to use "tableView.scrollRectToVisible". Use after calling tableView.reloadData(). In Swift 5

private func scrollAtTheBottom() {
    let lastIndexPath = IndexPath(row: state.myItemsArray.count - 1, section: 0)
    let lastCellPosition = tableView.rectForRow(at: lastIndexPath)
    tableView.scrollRectToVisible(lastCellPosition, animated: true)
}
Egzon P.
  • 4,498
  • 3
  • 32
  • 31
0

Swift 5 Here is a simple way to solve this problem

Steps:-> 1- When ViewDidLoad(), Then it will scroll 2- customTableView is IBoutlet's tableView var data: [String] = ["Hello", "This","is","Your","World"]

   override func viewDidLoad() {
   super.viewDidLoad()
  
3- In viewDidLoad we need to tell about indexPath
   /// data.count-1 will give last cell 
   let indexPath = IndexPath(row: data.count - 1, section:0)

   /// 1st Parameter: (at) will use for indexPath
   /// 2nd Parameter: (at) will use for position's scroll view
   /// 3rd Parameter: (animated) will show animation when screen will appear

   customtableView.scrollToRow(at:indexPath, at:.top, animated:true)
    /// Reload CustomTableView
   customTableView.reloadData()
-2

In Swift, you just need

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

to make it automatically scroll to the buttom

Even Cheng
  • 1,986
  • 19
  • 14