Reputation: 4355
How do I start a UITableView
scrolled to the last cell?
just have a plain UITableView(frame: CGRectZero, style: UITableViewStyle.Plain)
that when presented on screen, will start scrolled all the way to the bottom.
I've tried:
// 1
reloadData()
scrollToRowAtIndexPath(
NSIndexPath(forItem: dataArray.count-1, inSection: 0),
atScrollPosition: .Top, animated: false
)
// 2
reloadData()
var contentOffset = self.contentOffset
contentOffset.y = CGFloat.max
setContentOffset(contentOffset, animated: false)
on the tableView's init
method (in my subclass)
I've also tried the classic CGAffineTransformMakeScale(1,-1)
hack, but that makes my cells stick to the bottom and I want them stuck the the top (but scrolled to the bottom). (that is only relevant if I have few cells, when they don't fill the entire UITableView
space)
EDIT: another detail, I'm using dynamic cells UITableViewAutomaticDimension
.
Upvotes: 9
Views: 4794
Reputation: 385
You can either set the content offset:
tableview.contentOffset = CGPoint(x: ??, y: ??)
Or scroll to the desired row
tableview.contentOffset.scrollToItem(at: IndexPath(row: tableview.contentOffset.numberOfItems(inSection: 0) - 1, section: 0), at: .bottom, animated: false)
To get this to happen before the view appears so that the user doesn't see the transition, simply call these methods in the viewDidLayoutSubviews()
lifecycle method of your view controller.
Upvotes: 0
Reputation: 1918
This will scroll to bottom without any glitch, but if you use Tableview scroll-to-row property then there will be glitch.
For Swift 3 use
self.TableView.reloadData() // To populate your tableview first
//Since we have to wait until the table is reload
DispatchQueue.main.async {
let bottomOffset = CGPoint(x: 0, y: self.TableView.contentSize.height - self.TableView.frame.size.height)
self.TableView.setContentOffset(bottomOffset, animated: false)
}
For Objective C use
[YourTableView reloadData]; // To populate your tableview first
[YourTableView setContentOffset:CGPointMake(0, YourTableView.contentSize.height - YourTableView.frame.size.height)];
Upvotes: 8
Reputation: 391
EDIT:
animated: false
func scrollBottom() {
let lastIndex = NSIndexPath(forRow: dataArray.count-1, inSection: 0)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
}
TEST CODE:
import UIKit
class TableViewController: UITableViewController {
var goButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
goButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
goButton.backgroundColor = UIColor.blueColor()
goButton.addTarget(self, action: #selector(TableViewController.scrollBottom), forControlEvents: .TouchUpInside)
self.view.addSubview(goButton)
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 500
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = "Hello, World!"
return cell
}
func scrollBottom() {
let lastIndex = NSIndexPath(forRow: 499, inSection: 0)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
}
}
Upvotes: 1