6

I'm using the following code to determine if the last screen is visible on the screen to the user:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if indexPath.row == collection.count - 1 {
        print("last cell is seen!!")
        print(cell.frame)
    }
}

This works on small screens where the user has to scroll to get to the desired cell. However, on large screens where the whole table is visible, this method doesn't work. Is there any way to determine the distance between bottom of screen to the last cell in the UITableView?

Any help would be greatly appreciated. Thank you.

Edit: this is what I'm trying to accomplish.

if (last cell is visible && it is more than 100dp from bottom of screen) { display a fixed button on bottom of screen } else { add button to footer view of tableview so the user can scroll down to the button }

as diu
  • 1,010
  • 15
  • 31
  • But why would you want to know that? – Siyavash Sep 14 '17 at 00:07
  • if (last cell is visible && it is more than 100dp from bottom of screen) { display a fixed button on bottom of screen } else { add button to footer view of tableview so the user can scroll down to the button } this is the main reason I need to do that. Thank you for responding. – as diu Sep 14 '17 at 00:09
  • Ahh it makes sense now, please add this to the question as well. Also have you tried looking at the method "didEndDisplaying" – Siyavash Sep 14 '17 at 00:12
  • @Siyavash I just tried `didEndDisplaying` my friend and it doesn't seem to work for this case. Thank you. – as diu Sep 14 '17 at 00:17

4 Answers4

4

try it ! Hope to help you.

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    let contentOffsetMaxY: Float = Float(scrollView.contentOffset.y + scrollView.bounds.size.height)
    let contentHeight: Float = Float(scrollView.contentSize.height)

    let ret = contentOffsetMaxY > contentHeight - 100
    if ret {
        print("testButton is show");
    }else{
        print("testButton is hidden");
    }
}
CJiYI
  • 55
  • 1
  • 4
4

Swift 5

if let visiblePaths = tableView.indexPathsForVisibleRows,
    visiblePaths.contains([0, dataSourceArray.count - 1]) {
    // last cell is at least partially visible
}

indexPathsForVisibleRows is an array of IndexPath. However, there are a number of ways to express IndexPath (it has 7 initializers). indexPathsForVisibleRows utilizes IndexPath as an array literal (i.e. [0, 0] or [section 0, row 0]); therefore, to use indexPathsForVisibleRows, you must declare the path as an array literal and not in any other way (i.e. IndexPath(row: 0, section: 0)).

trndjc
  • 11,654
  • 3
  • 38
  • 51
3

I just created a project for you to show you one possible solution (there are many).

Basically you just need to get the last cell position, using

guard let lastCell = tableView.cellForRow(at: IndexPath(row: tableView.numberOfRows(inSection: 0)-1, section: 0)) else {
   return
}

let lastCellBottomY = lastCell.frame.maxY

Then knowing the tableView height, you can easily calculate the distance between the last cell and the bottom of the screen:

let delta = tableHeight - lastCellBottomY

And check if this distance is enough for you to show or not the fixed button:

if delta > 55 { 
   // ...show button
} else {
   // ...hide button
} 

For the dynamic button (the one you want to add below the last cell of the tableView when user scrolls), you could just add a new section with a custom cell to represent your button.

You can check out the whole idea via this link :

https://www.dropbox.com/s/7wpwv6737efnt5v/ButtonTable.zip?dl=0

Let me know if you have any questions :)

2

You can use this method to see if the last cell is visible or not

func isCellVisible(section:Int, row: Int) -> Bool {
    guard let indexes = self.indexPathsForVisibleRows else {
        return false
    }
    return indexes.contains {$0.section == section && $0.row == row }
}  }

Source

Then you can call it like

let lastCell = collection.count - 1
let result = isCellVisible(section:"Your Section Number", row: lastCell)
Siyavash
  • 970
  • 9
  • 23