How can I loop through UITableView's cells?

IosUitableview

Ios Problem Overview


I have n sections (known amount) and X rows in each section (unknown amount. Each row has a UITextField. When the user taps the "Done" button I want to iterate through each cell and do some conditional tests with the UITextField. If the tests pass data from each cell is written to a database. If not, then a UIAlert is shown. What is the best way to loop through the rows and if there is a more elegant solution to this please do advise.

Ios Solutions


Solution 1 - Ios

If you only want to iterate through the visible cells, then use

NSArray *cells = [tableView visibleCells];

If you want all cells of the table view, then use this:

NSMutableArray *cells = [[NSMutableArray alloc] init];
for (NSInteger j = 0; j < [tableView numberOfSections]; ++j)
{
    for (NSInteger i = 0; i < [tableView numberOfRowsInSection:j]; ++i)
    {
        [cells addObject:[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:j]]];
    }
}

Now you can iterate through all cells:
(CustomTableViewCell is a class, which contains the property textField of the type UITextField)

for (CustomTableViewCell *cell in cells)
{
    UITextField *textField = [cell textField];
    NSLog(@"%@"; [textField text]);
}

Solution 2 - Ios

Here is a nice swift implementation that works for me.

 func animateCells() {
        for cell in tableView.visibleCells() as! [UITableViewCell] {
            //do someting with the cell here.
            
        }
    }

Solution 3 - Ios

Accepted answer in swift for people who do not know ObjC (like me).

for section in 0 ..< sectionCount {
    let rowCount = tableView.numberOfRowsInSection(section)
    var list = [TableViewCell]()
    
    for row in 0 ..< rowCount {
        let cell = tableView.cellForRowAtIndexPath(NSIndexPath(forRow: row, inSection: section)) as! YourCell
        list.append(cell)
    }
}

Solution 4 - Ios

for xcode 9 use this - (similar to @2ank3th but the code is changed for swift 4):

let totalSection = tableView.numberOfSections
for section in 0..<totalSection
{
    print("section \(section)")
    let totalRows = tableView.numberOfRows(inSection: section)
   
    for row in 0..<totalRows
    {
        print("row \(row)")
        let cell = tableView.cellForRow(at: IndexPath(row: row, section: section))
        if let label = cell?.viewWithTag(2) as? UILabel
        {
            label.text = "Section = \(section), Row = \(row)"
        }
    }
}

Solution 5 - Ios

for (UIView *view in TableView.subviews) {
    for (tableviewCell *cell in view.subviews) {
       //do
    }
}

Solution 6 - Ios

Since iOS may recycle tableView cells which are off-screen, you have to handle tableView one cell at a time:

NSIndexPath *indexPath;
CustomTableViewCell *cell;

NSInteger sectionCount = [tableView numberOfSections];
for (NSInteger section = 0; section < sectionCount; section++) {
    NSInteger rowCount = [tableView numberOfRowsInSection:section];
    for (NSInteger row = 0; row < rowCount; row++) {
        indexPath = [NSIndexPath indexPathForRow:row inSection:section];
        cell = [tableView cellForRowAtIndexPath:indexPath];
        NSLog(@"Section %@ row %@: %@", @(section), @(row), cell.textField.text);
    }
}

You can collect an NSArray of all cells beforehands ONLY, when the whole list is visible. In such case, use [tableView visibleCells] to be safe.

Solution 7 - Ios

quick and dirty:

for (UIView *view in self.tableView.subviews){
    for (id subview in view.subviews){
        if ([subview isKindOfClass:[UITableViewCell class]]){
            UITableViewCell *cell = subview;
            // do something with your cell
        }
    }
}

Solution 8 - Ios

Here's a completely different way of thinking about looping through UITableView rows...here's an example of changing the text that might populate your UITextView by looping through your array, essentially meaning your tableView cell data.

All cells are populated with data from some kind of model. A very common model would be using an NSObject and NSMutableArray of those objects. If you were in didSelectRowAtIndexPath, you would then want to do something like this to affect the row you're selecting after modifying the array above:

for(YourObject *cellRow in yourArray)
{
    if(![cellRow.someString isEqualToString:@""])
    {
         cellRow.someString = @"";
    }
    //...tons of options for conditions related to your data
}

YourObject *obj = [yourArray objectAtIndex:indexPath.row];
obj.someString = @"selected";
[yourArray insertObject:views atIndex:indexPath.row];
[yourArray removeObjectAtIndex:indexPath.row];
[yourTable reloadData];

This code would remove all the UITextField's text in every row except the one you selected, leaving the text "selected" in the tapped cell's UITextField as long as you're using obj.someString to populate the field's text in cellForRowAtIndexPath or willDisplayRowAtIndexPath using YourObject and yourArray.

This type of "looping" doesn't require any conditions of visible cells vs non visible cells. If you have multiple sections populated by an array of dictionaries, you could use the same logic by using a condition on a key value. Maybe you want to toggle a cells imageView, you could change the string representing the image name. Tons of options to loop through the data in your tableView without using any delegated UITableView properties.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser810606View Question on Stackoverflow
Solution 1 - IosPaul WarkentinView Answer on Stackoverflow
Solution 2 - IosandrewCanProgramView Answer on Stackoverflow
Solution 3 - Ios2ank3thView Answer on Stackoverflow
Solution 4 - IosluhuiyaView Answer on Stackoverflow
Solution 5 - IosDarshit ShahView Answer on Stackoverflow
Solution 6 - IosJOMView Answer on Stackoverflow
Solution 7 - IosbudiDinoView Answer on Stackoverflow
Solution 8 - IoswhyozView Answer on Stackoverflow