Déterminer si une cellule de table est visible

Est-il possible de savoir si une cellule de table est actuellement visible? J’ai une tableview dont la première cellule (0) est une barre de recherche. Si une recherche n’est pas active, masquez la cellule 0 par un décalage. Lorsque la table ne comporte que quelques lignes, la ligne 0 est visible. Comment déterminer si la ligne 0 est visible ou la ligne supérieure?

UITableView a une méthode d’instance appelée indexPathsForVisibleRows qui renvoie un object NSArray d’objects NSIndexPath pour chaque ligne de la table actuellement visible. Vous pouvez vérifier cette méthode avec la fréquence nécessaire et vérifier la bonne ligne. Par exemple, si tableView est une référence à votre table, la méthode suivante vous dira si la ligne 0 est à l’écran ou non:

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

Étant donné que la méthode UITableView renvoie le NSIndexPath , vous pouvez tout simplement l’étendre pour rechercher des sections ou des combinaisons de lignes / sections.

Cela vous est plus utile que la méthode visibleCells , qui renvoie un tableau d’objects de cellules de tableau. Les objects de la cellule de tableau sont recyclés. Par conséquent, dans les grands tableaux, ils n’auront finalement aucune corrélation simple avec votre source de données.

Pour vérifier que la cellule de table est visible ou n’utilise pas ce code de ligne

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

ici newIndexPath est IndexPath de la cellule de vérification …..

Swift 3.0

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

Je l’utilise dans 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 } } } 

Une autre solution (qui peut également être utilisée pour vérifier si une ligne est entièrement visible) serait de vérifier si le cadre de la row trouve dans le tableview visible de la tableview .

Dans le code suivant, ip représente le NSIndexPath :

 CGRect cellFrame = [tableView rectForRowAtIndexPath:ip]; if (cellFrame.origin.ytableView.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]; } 

Utiliser également cellForRowAtIndexPath: devrait fonctionner, car il retourne un object nil si la ligne n’est pas visible:

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

Version rapide:

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

Notez que “Quelque peu visible” est “visible”. De plus, dans viewWillAppear, vous pouvez obtenir de faux positifs à partir de indexPathsForVisibleRows fur et à indexPathsForVisibleRows que la mise en page est en cours et si vous layoutIfNeeded() la dernière ligne, même appeler layoutIfNeeded() ne vous aidera pas. Vous voudrez vérifier les choses dans / après viewDidAppear .

Ce code swift 3.1 désactivera le défilement si la dernière ligne est entièrement visible. Appelez-le dans / après 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 }