Swift 5, iOS 12 tested
Code This code works fine for a UITableView , even if there are sections with 0 elements (which will crash in any other solution I have seen 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) } }
Code This code works for UIScrollView , but will not work for UITableView , which has more cells than one screen can accommodate, due to the strange internal implementation of Apple's 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) } }
source share