Reputation: 3318
How can I detect when a UITableView
has been scrolled to the bottom so that the last cell is visible?
Upvotes: 22
Views: 36534
Reputation: 6013
Swift 5+
//Show Last Cell (for Table View)
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
if indexPath.row == (yourdataArray.count - 1)
{
print("came to last row")
}
}
//Show last cell (for Collection View)
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
{
if indexPath.row == (yourdataArray.count - 1)
{
// Last cell is visible
}
}
Upvotes: 4
Reputation: 151
I found this solution:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let contentOffsetMaxY: Float = Float(scrollView.contentOffset.y + scrollView.bounds.size.height)
let contentHeight: Float = Float(scrollView.contentSize.height)
let lastCellIsVisible = contentOffsetMaxY > contentHeight + somePaddingIfWanted
if lastCellIsVisible {
doSomething()
}
}
Upvotes: 1
Reputation: 13013
I had some problems with the willDisplayCell method. This works for me:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let y = scrollView.contentOffset.y/(scrollView.contentSize.height - scrollView.frame.size.height)
let relativeHeight = 1 - (table.rowHeight / (scrollView.contentSize.height - scrollView.frame.size.height))
if y >= relativeHeight{
print("last cell is visible")
}
}
Just pass this in the delegate methods, and change 'table' to your tableView.
Upvotes: 0
Reputation: 61774
Create elegant extension for UITableView
:
extension UITableView {
func isLast(for indexPath: IndexPath) -> Bool {
let indexOfLastSection = numberOfSections > 0 ? numberOfSections - 1 : 0
let indexOfLastRowInLastSection = numberOfRows(inSection: indexOfLastSection) - 1
return indexPath.section == indexOfLastSection && indexPath.row == indexOfLastRowInLastSection
}
}
Example of usage:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView.isLast(for: indexPath) {
//do anything then
}
return cell
}
Upvotes: 8
Reputation: 456
For Xcode 8 and swift 3
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastSectionIndex = tableView.numberOfSections - 1
let lastRowIndex = tableView.numberOfRows(inSection: lastSectionIndex) - 1
if indexPath.section == lastSectionIndex && indexPath.row == lastRowIndex {
print("this is the last cell")
}
}
Upvotes: 3
Reputation: 27353
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger lastSectionIndex = [tableView numberOfSections] - 1;
NSInteger lastRowIndex = [tableView numberOfRowsInSection:lastSectionIndex] - 1;
if ((indexPath.section == lastSectionIndex) && (indexPath.row == lastRowIndex)) {
// This is the last cell
}
}
Upvotes: 14
Reputation: 14235
Inside tableView:cellForRowAtIndexPath:
or tableView:willDisplayCell:forRowAtIndexPath:
like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
NSInteger sectionsAmount = [tableView numberOfSections];
NSInteger rowsAmount = [tableView numberOfRowsInSection:[indexPath section]];
if ([indexPath section] == sectionsAmount - 1 && [indexPath row] == rowsAmount - 1) {
// This is the last cell in the table
}
...
}
Upvotes: 41
Reputation: 8757
Implement the tableView:willDisplayCell:forRowAtIndexPath:
method in your UITableViewDelegate and check to see if it's the last row.
Upvotes: 27