web-dev-qa-db-fra.com

iOS - Comment puis-je obtenir le chemin IndexPath du dernier élément d'une vue de table?

Je voudrais faire défiler automatiquement à la fin d'une vue de table.

[tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

Étant donné que je sais combien d'éléments sont dans la tableview en utilisant:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

Comment puis-je obtenir IndexPath * jusqu'au dernier élément de cette tableView? Cela est nécessaire pour que je puisse le fournir comme argument de scrollToRowAtIndexPath: atScrollPosition: animated

Merci!

25
Nick

Vous pouvez obtenir le indexPath de la dernière ligne de la dernière section comme ceci.

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(numberOfRowsInLastSection - 1) inSection:(numberOfSections - 1)];

Ici, numberOfSections est la valeur que vous renvoyez depuis la méthode numberOfSectionsInTableView:. Et, numberOfRowsInLastSection est la valeur que vous renvoyez de la méthode numberOfRowsInSection: pour la dernière section de la vue tableau.

Cela peut être placé dans une sous-classe ou une catégorie pour le rendre facile:

-(NSIndexPath*)indexPathForLastRow
{
    return [NSIndexPath indexPathForRow:[self numberOfRowsInSection:self.numberOfSections - 1] - 1 inSection:self.numberOfSections - 1];
}
30
EmptyStack

Pour obtenir une référence à la dernière ligne de la dernière section…

// First figure out how many sections there are
NSInteger lastSectionIndex = [tableView numberOfSections] - 1;

// Then grab the number of rows in the last section
NSInteger lastRowIndex = [tableView numberOfRowsInSection:lastSectionIndex] - 1;

// Now just construct the index path
NSIndexPath *pathToLastRow = [NSIndexPath indexPathForRow:lastRowIndex inSection:lastSectionIndex];
31
Ryan Grimm

Dans Swift 3

let lastRowIndex = tableView.numberOfRows(inSection: tableView.numberOfSections-1)

if (indexPath.row == lastRowIndex - 1) {
     print("last row selected")
}
10
Omer Janjua

Il est probable que quelqu'un aura besoin de la même chose pour UICollectionView, J'ai donc mis à jour la réponse de Ryan Grimm :

NSInteger lastSectionIndex = [self.collectionView numberOfSections] - 1;
NSInteger lastItemIndex = [self.collectionView numberOfItemsInSection:lastSectionIndex] - 1;
NSIndexPath *pathToLastItem = [NSIndexPath indexPathForItem:lastItemIndex inSection:lastSectionIndex];
9
Shmidt

Voici une extension dans Swift 4.x qui prend en compte le fait qu’il peut ne pas y avoir de rangées afin d’éviter les plantages hors de portée.

import UIKit

extension UITableView {
    func lastIndexpath() -> IndexPath {
        let section = max(numberOfSections - 1, 0)
        let row = max(numberOfRows(inSection: section) - 1, 0)

        return IndexPath(row: row, section: section)
    }
}

Puis appelez-le depuis votre contrôleur de vue avec:

let lastIndexPath = tableView.lastIndexPath()
7
CodeBender

essaye ça:

Dans cellForRowAtIndexPath

if(indexPath.row == myArray.count -1)

{
     myIndexPath = indexpath;
}

myIndexPath doit être un objet de NSIndexPath

7
Meghan

La plupart des réponses ici, y compris la réponse acceptée, ne prennent pas en compte les cas valables d'une vue tabulaire avec zéro section ou d'une section finale avec zéro ligne. 

La meilleure façon de représenter ces situations est d'utiliser un index de NSNotFound, accepté par UIKit dans des méthodes telles que scrollToRowAtIndexPath:atScrollPosition:animated:.

NSNotFound est un index de ligne valide permettant de faire défiler une section avec zéro ligne.

J'utilise la méthode suivante: 

- (NSIndexPath *)bottomIndexPathOfTableView:(UITableView *)tableView
{
    NSInteger finalSection = NSNotFound;
    NSInteger finalRow = NSNotFound;

    NSInteger numberOfSections = [tableView numberOfSections];
    if (numberOfSections)
    {
        finalSection = numberOfSections - 1;
        NSInteger numberOfRows = [tableView numberOfRowsInSection:finalSection];
        if (numberOfRows)
        {
            finalRow = numberOfRows - 1;
        }
    }
    return numberOfSections ? [NSIndexPath indexPathForRow:finalRow inSection:finalSection] : nil;
}
3
johnpatrickmorgan

Il semble que toutes les solutions ne considèrent pas que la dernière section peut ne pas avoir de lignes du tout. Donc, voici une fonction qui retourne la dernière ligne d'une dernière section non vide:

Swift 3:

extension UITableViewDataSource {
    func lastIndexPath(_ tableView: UITableView) -> IndexPath? {
        guard let sections = self.numberOfSections?(in: tableView) else { return nil }
        for section in stride(from: sections-1, through: 0, by: -1) {
            let rows = self.tableView(tableView, numberOfRowsInSection: section)
            if rows > 0 {
                return IndexPath(row: rows - 1, section: section)
            }
        }
        return nil
    }
}

Exemple:

class ViewController: UIViewController {

    //...

    func scrollToLastRow() {
        if let indexPath = lastIndexPath(tableView) {
            tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
        }
    }
}

extension ViewController: UITableViewDataSource {
    //required data source methods
}
2
alexburtnik

Réponse rapide 3, avec des vérifications hors limites. Implémenté en tant qu'extension tableview

extension UITableView {

    var lastIndexPath: IndexPath? {

        let lastSectionIndex = numberOfSections - 1
        guard lastSectionIndex >= 0 else { return nil }

        let lastIndexInLastSection = numberOfRows(inSection: lastSectionIndex) - 1
        guard lastIndexInLastSection >= 0 else { return nil }

        return IndexPath(row: lastIndexInLastSection, section: lastSectionIndex)
    }
}
1
Mark Bridges

Essayez ce code:

//   get number of section
let indexOfLastSection = self.yourTableView.numberOfSections - 1

// Then get the number of rows in the last section

if indexOfLastSection >= 0{
    let indexOfLastRow = self.yourTableView.numberOfRows(inSection: indexOfLastSection) - 1
    if indexOfLastRow >= 0{
        let pathToLastRow = IndexPath.init(row: indexOfLastRow, section: indexOfLastSection)
    }
}
0
Brijesh Shiroya