web-dev-qa-db-fra.com

Comment obtenir toutes les cellules dans un UITableView

Disons que j'ai un UITableView qui a plusieurs lignes. Je veux obtenir tous les UITableViewCells en tant que NSArray à un moment donné. j'ai essayé 

[tableView visibleCells] 

mais il y a un problème avec cette approche: je ne peux pas avoir toutes les cellules qui ne sont pas actuellement dans l'écran actuel. Alors je me suis tourné vers une autre approche:

-(NSArray *)cellsForTableView:(UITableView *)tableView
{
    NSInteger sections = tableView.numberOfSections;
    NSMutableArray *cells = [[NSMutableArray alloc]  init];
    for (int section = 0; section < sections; section++) {
        NSInteger rows =  [tableView numberOfRowsInSection:section];
        for (int row = 0; row < rows; row++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];   // **here, for those cells not in current screen, cell is nil**
            [cells addObject:cell];
        }
    }
    return cells;
}

mais semble que cette approche ne peut toujours pas obtenir ces cellules qui ne sont pas affichées à l'écran. Quelqu'un peut-il m'aider à ce sujet?

30
David L

Je ne pense pas que ce soit possible, simplement parce que la tableView ne stocke pas toutes les cellules. Il utilise un mécanisme de mise en cache qui stocke uniquement certaines cellules non visibles à des fins de réutilisation. 

Pourquoi avez-vous besoin de toutes les cellules? Peut-être que vous pouvez réaliser ce que vous essayez de faire, sinon.

21
Tobi

Voici la solution la plus simple dans Swift 3.0

func getAllCells() -> [UITableViewCell] {

    var cells = [UITableViewCell]()
    // assuming tableView is your self.tableView defined somewhere
    for i in 0...tableView.numberOfSections-1
    {
        for j in 0...tableView.numberOfRowsInSection(i)-1
        {
            if let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: j, inSection: i)) {

               cells.append(cell)
            }

        }
    }
 return cells
 }
12
Vakas

Chaque fois que vous créez une cellule, vous pouvez l'ajouter à un NSMutableArray que vous pouvez analyser à tout moment:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CustomCell *Cell = [self dequeueReusableCellWithIdentifier:@"Custom_Cell_Id"];
    if (Cell == NULL)
    {
        Cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Custom_Cell_Id"]];
        [Cells_Array addObject:Cell];
    }
}

- (void) DoSomething
{
    for (int i = 0;i < [Cells count];i++)
    {
        CustomCell *Cell = [Cells objectAtIndex:i];
        //Access cell components
    }
}
6
Unreal Dragon

Solution fonctionnelle Swift 4.1 ????

extension UITableViewDataSource where Self:UITableView {
   /**
    * EXAMPLE: tableView.cells//list of cells in a tableview
    */
   var cells:[UITableViewCell] {
       return (0..<self.numberOfSections).indices.map { (sectionIndex:Int) -> [UITableViewCell] in
           return (0..<self.numberOfRows(inSection: sectionIndex)).indices.compactMap{ (rowIndex:Int) -> UITableViewCell? in
               return self.cellForRow(at: IndexPath(row: rowIndex, section: sectionIndex))
         }
       }.flatMap{$0}
    }
}
1
eonist

Je pense que vous avez peut-être mal compris comment la variable UITableView est mise en œuvre. Le point important à comprendre est que les cellules qui ne sont pas visibles n’existent pas (ou du moins qu’elles ne le pourraient pas).

Lorsque UITableView défile, les anciennes cellules sont remplacées par de nouvelles cellules en vertu de dequeueReusableCellWithIdentifier utilisé dans

-(UITableViewCell) cellForRowAtIndexPath (NSIndexPath *)indexPath
1
AppleDelegate

Cependant, une implémentation plus simple pour obtenir les cellules actuelles utiliserait Set i.e O(1)

/// Reference to all cells.
private var allCells = Set<UITableViewCell>()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Your_Cell_ID") as! UITableViewCell
    if !allCells.contains(cell) { allCells.insert(cell) }
    return cell
}
0
Mazen Kasser

Je suppose que j'ai trouvé un truc pour ce problème. Essaye ça ;)

self.tableView.frame = CGRectMake(self.tableView.frame.Origin.x, self.tableView.frame.Origin.y, self.tableView.contentSize.width, self.tableView.contentSize.height);

UITableView appelez cellForRowAtIndexPath en fonction de la hauteur de tableView.frame. Vous devez donc mettre à jour la hauteur de votre tableView.

0
Reza Dehnavi

Voulez-vous la valeur de ces champs de texte? Si oui, vous pouvez accéder via la propriété tag du champ de texte avec indexpath.row

0