Determine if the table cell is visible.

Is there a way to find out if a table cell is currently displayed? I have a tableview whose first cell (0) is a uisearchbar. If the search is not active, then hide cell 0 through the offset. When a table has only a few rows, row 0 is visible. How to determine if row 0 is visible or is the top row?

+47
iphone uitableview
Jul 24 '10 at 19:58
source share
7 answers

UITableView has an instance method called indexPathsForVisibleRows that returns an NSArray objects for each row in the table that are currently visible. You can check this method at any frequency you need and check the correct line. For example, if tableView is a link to your table, the following method will tell you if row 0 is displayed on the screen:

 -(BOOL)isRowZeroVisible { NSArray *indexes = [tableView indexPathsForVisibleRows]; for (NSIndexPath *index in indexes) { if (index.row == 0) { return YES; } } return NO; } 

Since the UITableView method returns NSIndexPath , you can just as easily expand it to look for sections or row / section combinations.

This is more useful for you than the visibleCells method, which returns an array of table cell objects. Table cell objects are returned, so in large tables, they will ultimately not have a simple correlation with your data source.

+91
Jul 24 2018-10-24T00:
source share

To check the tableview cell is visible or not to use this row code

  if(![tableView.indexPathsForVisibleRows containsObject:newIndexPath]) { // your code } 

here newIndexPath is an IndexPath cell check .....

Swift 3.0

 if !(tableView.indexPathsForVisibleRows?.contains(newIndexPath)) { // Your code here } 
+35
09 Oct
source share

I use this in Swift 3.0

 extension UITableView { /// Check if cell at the specific section and row is visible /// - Parameters: /// - section: an Int reprenseting a UITableView section /// - row: and Int representing a UITableView row /// - Returns: True if cell at section and row is visible, False otherwise func isCellVisible(section:Int, row: Int) -> Bool { guard let indexes = self.indexPathsForVisibleRows else { return false } return indexes.contains {$0.section == section && $0.row == row } } } 
+6
Jan 17 '17 at 10:15
source share

Another solution (which can also be used to check that the row tableview visible) would be to check if the frame for row inside the visible rectangle of the tableview .

In the following code, ip represents NSIndexPath :

 CGRect cellFrame = [tableView rectForRowAtIndexPath:ip]; if (cellFrame.origin.y<tableView.contentOffset.y) { // the row is above visible rect [tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO]; } else if(cellFrame.origin.y+cellFrame.size.height>tableView.contentOffset.y+tableView.frame.size.height-tableView.contentInset.top-tableView.contentInset.bottom){ // the row is below visible rect [tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:NO]; } 

Also using cellForRowAtIndexPath: should work, since it returns an nil object if the row is not visible:

 if([tableView cellForRowAtIndexPath:ip]==nil){ // row is not visible } 
+4
Nov 12 '13 at 8:55
source share

Quick version:

 if let indices = tableView.indexPathsForVisibleRows { for index in indices { if index.row == 0 { return true } } } return false 
+4
Nov 07 '15 at 18:34
source share

IOS 4:

 NSArray *cellsVisible = [tableView indexPathsForVisibleRows]; NSUInteger idx = NSNotFound; idx = [cellsVisible indexOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { return ([(NSIndexPath *)obj compare:indexPath] == NSOrderedSame); }]; if (idx == NSNotFound) { 
+1
Mar 29 '11 at 13:25
source share

Note that “somewhat visible” is “visible”. Also, in viewWillAppear, you can get false positives from indexPathsForVisibleRows as the layout executes, and if you look at the last line, even calling layoutIfNeeded() will not help you for tables. You will want to check everything in / after viewDidAppear .

This quick 3.1 code will disable scrolling if the last line is completely visible. Call it in / after viewing DidAppear.

  let numRows = tableView.numberOfRows(inSection: 0) // this can't be in viewWillAppear because the table frame isn't set to proper height even after layoutIfNeeded() let lastRowRect = tableView.rectForRow(at: IndexPath.init(row: numRows-1, section: 0)) if lastRowRect.origin.y + lastRowRect.size.height > tableView.frame.size.height { tableView.isScrollEnabled = true } else { tableView.isScrollEnabled = false } 
0
Mar 31 '17 at 1:23
source share



All Articles