I need to make a request when the user saw the UITableViewCell, I used func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
but this method call for each UITableViewCell, before it's displayed, but I need a delegate when UITableViewCell appeared in the screen.
Asked
Active
Viewed 1,357 times
0

Hamed
- 1,678
- 18
- 30
-
I think you can use delegate method from cell layoutSubviews for same. – golu_kumar Apr 24 '20 at 20:02
-
No, `layoutSubviews` call for each cell when the table view is in loading – Hamed Apr 24 '20 at 20:28
-
willDisplay will also called for each cell when table view is about for loading. – golu_kumar Apr 24 '20 at 21:05
-
It's something like this, but it seems it works randomly, does not call respectively – Hamed Apr 25 '20 at 05:15
-
Does the cell have to be completely visible, or is it okay if the cell is partially visible? There are ways to accomplish both. – Rob C Apr 25 '20 at 07:51
1 Answers
1
What you need to do is detect when scrolling occurs by implementing the scrollViewDidScroll(_:)
delegate method. When the delegate method is called you can determine which cells are visible by checking the tableView.indexPathsForVisibleRows
property. Note that this property returns the IndexPath for all cells that are both fully visible and partially visible.
Assuming you that you are only concerned with cells that are fully visible, you can check the frame for each row to determine if it is in fact fully visible.
To determine which cells are newly visible, you need to keep track of cells that were previously visible and compare the two sets.
This code will let you know as soon as soon as a cell is displayed:
var previousVisiblePaths = Set<IndexPath>()
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let visiblePaths = tableView.indexPathsForVisibleRows?.filter ({
let rect = tableView.rectForRow(at: $0)
return tableView.bounds.contains(rect)
}).reduce(into: Set<IndexPath>(), { result, indexPath in
result.insert(indexPath)
}) else { return }
let newVisiblePaths = visiblePaths.subtracting(previousVisiblePaths)
if newVisiblePaths.count > 0 {
print("Just displayed: \(newVisiblePaths)")
}
previousVisiblePaths = visiblePaths
}

Rob C
- 4,877
- 1
- 11
- 24
-
It depends on the user scroll if the user does not scroll view what should do for presented cells – Hamed Apr 25 '20 at 10:10
-
get tableView.indexPathsForVisibleRows at viewDidAppear() or at viewDidLayoutSubviews() – Roi Zakai Apr 25 '20 at 10:21
-
I upvoted this answer, but I want a better solution, `scrollViewDidScroll` will call for a little scroll in table view, so filtering `indexPathsForVisibleRows` in this method is costly. – Hamed Apr 26 '20 at 17:16