iPad: Iterate over every cell in a UITableView?

To iterate over every visible cell in a UITableView:

for (UITableViewCell *cell in self.tableView.visibleCells) {
    NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:cell];

(edited to better state answer and hope that this is indexed more accurately for search results with the intention of saving others more time in the future)


(This builds on aroths answer.)

I like to define this as a category to UITableView so it's available everywhere.

(As mentioned a few times, you should be sure you really want to iterate over the cells themselves. For example: I use this to clear the UITableViewAccessoryCheckmark's from all the cells before setting it to the user selected cell. A good rule of thumb is to do this only if the datasource methods can't do what you need to.)

Define like this:

- (void)enumerateCellsUsingBlock:(void (^)(UITableViewCell *cell))cellBlock {
    NSParameterAssert(cellBlock != nil);
    for (int section = 0; section < [self numberOfSections]; section++) {
        for (int row = 0; row < [self numberOfRowsInSection:section]; row++) {
            NSIndexPath *cellPath = [NSIndexPath indexPathForRow:row inSection:section];
            UITableViewCell *cell = [self cellForRowAtIndexPath:cellPath];
            if (cellBlock != nil) {
                cellBlock(cell);
            }
        }
    }
}

Call like this:

[self.tableView enumerateCellsUsingBlock:^(UITableViewCell *cell) {
    NSLog(@"cell:%@", cell);
}];

It would be good style to typedef the block, too.


for (int section = 0; section < [tableView numberOfSections]; section++) {
    for (int row = 0; row < [tableView numberOfRowsInSection:section]; row++) {
        NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
        UITableViewCell* cell = [tableView cellForRowAtIndexPath:cellPath];
        //do stuff with 'cell'
    }
}