web-dev-qa-db-fra.com

Déterminer si une cellule de table est visible

Existe-t-il un moyen de savoir si une cellule de la table est actuellement visible? __. Lorsque la table ne comporte que quelques lignes, la ligne 0 est visible . Comment déterminer si la ligne 0 est visible ou si la ligne du haut est?

53
Jim B

UITableView a une méthode d'instance appelée indexPathsForVisibleRows qui renverra un NSArray de NSIndexPath objets pour chaque ligne de la table actuellement visibles. Vous pouvez vérifier cette méthode avec la fréquence souhaitée et vérifier la rangée appropriée. Par exemple, si tableView est une référence à votre table, la méthode suivante vous dira si la ligne 0 est affichée ou non à l'écran:

-(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 la NSIndexPath, vous pouvez également l'étendre pour rechercher des sections ou des combinaisons ligne/section.

Cela vous est plus utile que la méthode visibleCells, qui renvoie un tableau d'objets de cellules de tableau. Les objets de cellules 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.

98
Devunwired

Pour vérifier la table tableview est visible ou non utiliser ce code de ligne 

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

ici newIndexPath est IndexPath de la cellule de contrôle .....

Swift 3.0

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

}
40
Anand Mishra

J'utilise ceci 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 }
    }  }
11
Emil

Version rapide:

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

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 variable row se situe dans le rect visible de la variable tableview.

Dans le code suivant, ip représente la 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];
}

Utiliser également cellForRowAtIndexPath: devrait fonctionner, car il renvoie un objet nil si la ligne n'est pas visible:

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

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
CSmith

Notez que "Un peu visible" est "visible". De plus, dans viewWillAppear, vous pourriez obtenir de faux positifs de indexPathsForVisibleRows pendant la mise en page, et si vous regardez à la dernière ligne, même appeler layoutIfNeeded() ne vous aidera pas pour les tables. 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
    }
0
xaphod