I would like to load my tableview backwards, meaning the the tableView loads from bottom and scroll up to see more content.
First, I tried reversing the dataSource array. The contents are reversed, but, it still loads from the top, and the user has to scroll down to see more content.
I then tried loading the tableView from the bottom in viewWillAppear:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if (self.conversationTableView.contentSize.height > self.conversationTableView.frame.size.height) {
let offset = CGPoint(x: CGFloat(0), y: CGFloat(self.conversationTableView.contentSize.height - self.conversationTableView.frame.size.height))
self.conversationTableView.setContentOffset(offset, animated: true)
}
}
This attempt, however does not work since I am asynchronously downloading images (I'm using NSTextAttachment, which fills my UITextView within each cell). Everytime my placeholder is replaced with the real downloaded image, it causes the tableView content offset to shift (the placeholder's image height is almost always smaller than the height of downloaded image). So setting the contentOffset this way does not work.
How does one load the tableView from the bottom and scroll up to see more content?
To scroll to the top of our tableview we need to create a new IndexPath . This index path has two arguments, row and section . All we want to do is scroll to the top of the table view, therefore we pass 0 for the row argument and 0 for the section argument. UITableView has the scrollToRow method built in.
The best way was to flip the tableView and it's cells. This way, if a cell were to change size (due to things like asynchronous downloading), you will still load from the bottom of the tableview than at an offset.
//In ViewDidLoad
conversationTableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi));
//In cellForRowAtIndexPath
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi));
Also: If you have a headerView, simply set it to the tableView.tableFooterView
:
var tableHeaderView = UIView(frame: headerFrame)
tableHeaderView.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi));
conversationTableView.tableFooterView = tableHeaderView
And if you have a footerView and headerView, just set the header to the footer, and the footer to the header.
Edit: If you want to flip the scroll indicator:
conversationTableView.scrollIndicatorInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, conversationTableView.bounds.size.width - 8.0)
In your viewWillAppear
method, do the following:
tableView.scrollToRowAtIndexPath(bottomIndexPath, atScrollPosition: .Bottom,
animated: true)
Where bottomIndexPath
is the indexPath for the final row in your table view. If you have an array of length n
and only one section in your table, this will usually be IndexPath(item: n-1, section: 0)
, but be sure to check your specific UITableView
.
This will ensure you start off at the bottom of the tableView. Having done that, all you need to do is ensure your cellForRowAtIndexPath
method on your UITableViewDataSource
returns the data in reverse and you'll get the effect you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With