确定一个tableview单元格是否可见

有什么办法来知道如果一个tableview单元格是目前可见? 我有一个tableview的第一个单元格(0)是一个uisearchbar。 如果search未激活,则通过偏移量隐藏单元格0。 当表只有几行时,行0是可见的。 如何确定第0行是可见的还是第一行?

UITableView有一个名为indexPathsForVisibleRows的实例方法,它将为表中当前可见的每一行返回一个NSIndexPath对象的NSArray 。 你可以用你需要的任何频率检查这个方法,并检查正确的行。 例如,如果tableView是对表的引用,下面的方法会告诉你行0是否在屏幕上:

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

因为UITableView方法返回NSIndexPath ,所以可以轻松地扩展它以查找节或行/节组合。

这比visibleCells方法更有用,它返回一个表格单元格对象的数组。 表单元对象被循环使用,所以在大表中它们最终不会有简单的相关性返回到数据源。

检查tableview单元格是否可见或不使用此代码行

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

这里newIndexPath是检查单元格的索引path…..

Swift 3.0

 if !(tableView.indexPathsForVisibleRows?.contains(newIndexPath)) { // Your code here } 

我在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 } } } 

另一个解决scheme(也可以用来检查一行是否完全可见)将检查该row的框架是否在tableview的可见矩形内。

在下面的代码中, ip表示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]; } 

也使用cellForRowAtIndexPath:应该工作,因为如果行不可见,它返回一个nil对象:

 if([tableView cellForRowAtIndexPath:ip]==nil){ // row is not visible } 

Swift版本:

 if let indices = tableView.indexPathsForVisibleRows { for index in indices { if index.row == 0 { return true } } } return false 

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) { 

请注意,“有点可见”是“可见的”。 另外,在viewWillAppear中,当布局正在进行时,您可能会从indexPathsForVisibleRows获得误报,如果您正在查看最后一行,则即使调用layoutIfNeeded()也无法帮助您处理表格。 你会想检查/ viewDidAppear后的东西。

如果最后一行是完全可见的,这个swift 3.1代码将禁止滚动。 在viewDidAppear之后调用它。

  let numRows = tableView.numberOfRows(inSection: 0) // this can't be in viewWillAppear because the table's 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 }