UITableView scroll to bottom
Scrolling to tableViewCell
?
//for instance, you have 15 cells
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:14 inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
Swift 5, iOS 12 tested
ð This code works perfectly for UITableView
, even if there are sections with 0 elements (which will crash in every other solution I saw on the Internet)
extension UITableView {
func scrollTableViewToBottom(animated: Bool) {
guard let dataSource = dataSource else { return }
var lastSectionWithAtLeasOneElements = (dataSource.numberOfSections?(in: self) ?? 1) - 1
while dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeasOneElements) < 1 {
lastSectionWithAtLeasOneElements -= 1
}
let lastRow = dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeasOneElements) - 1
guard lastSectionWithAtLeasOneElements > -1 && lastRow > -1 else { return }
let bottomIndex = IndexPath(item: lastRow, section: lastSectionWithAtLeasOneElements)
scrollToRow(at: bottomIndex, at: .bottom, animated: animated)
}
}
fixed version from Kevin in this topic, preventing infinite scroll for tableView with 0
items:
Source: https://stackoverflow.com/a/59470799/9763761
func scrollToBottom(animated: Bool) {
guard let dataSource = dataSource else { return }
var lastSectionWithAtLeastOneElement = (dataSource.numberOfSections?(in: self) ?? 1) - 1
while dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeastOneElement) < 1 && lastSectionWithAtLeastOneElement > 0 {
lastSectionWithAtLeastOneElement -= 1
}
let lastRow = dataSource.tableView(self, numberOfRowsInSection: lastSectionWithAtLeastOneElement) - 1
guard lastSectionWithAtLeastOneElement > -1 && lastRow > -1 else { return }
let bottomIndex = IndexPath(item: lastRow, section: lastSectionWithAtLeastOneElement)
scrollToRow(at: bottomIndex, at: .bottom, animated: animated)
}
ð This code works for UIScrollView
, but won't work for UITableView
that have more cells then one screen can fit, because of Apple's weird internal implementation of UITableViewController
:
extension UIScrollView {
func scrollToBottom(animated: Bool) {
guard contentSize.height > bounds.size.height else { return }
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
setContentOffset(bottomOffset, animated: true)
}
}