Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS - cellForRowAtIndexPath skip row

Basically, the cellForRowAtIndexPath function need to return a UITableViewCell. In my code, I would like to check a behaviour that will check something and skip the cell if a specific value is found.

Here's what I have right now :

static NSString *FirstCellIdentifier = @"First Custom Cell";
static NSString *SecondCellIdentifier = @"Second Custom Cell";

CustomObject *o = [_customObjects objectAtIndex:indexPath.row];

if ([s.name isEqualToString:@""])
{
    FirstCellController *cell = [customList dequeueReusableCellWithIdentifier:FirstCellIdentifier];
    if (!cell) { 
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"FirstCustomCell" owner:self options:nil];
        for (id currentObject in topLevelObjects){
            if ([currentObject isKindOfClass:[UITableViewCell class]]){
                cell = (FirstCellController *) currentObject;
                break;
            }
        }
    }
    // Here I do something with the cell's content
    return cell;
}
else {
    SecondCellController *cell = [customList dequeueReusableCellWithIdentifier:SecondCellIdentifier];
    if (!cell) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"SecondCustomCell" owner:self options:nil];
        for (id currentObject in topLevelObjects){
            if ([currentObject isKindOfClass:[UITableViewCell class]]){
                cell = (SecondCellController *) currentObject;
                break;
            }
        }
    }
    // Here i do something with the cell's content
    return cell;
}

What I'd like to do is that if the s.name is not empty, I would like to "skip" the cell, not displaying it and go to the next one.

Anyone have some advice on this please ?

Thanks.

like image 996
B F Avatar asked Oct 11 '12 15:10

B F


2 Answers

You cannot "skip" a cell this way. If your datasource claims there are n rows, then you have to provide a cell for each of them. The correct way would be to modify your datasource to claim (n-1) rows when you want to remove one, then call UITableView reloadData to have it regenerate the table (and ask you for new cells for each visible row).

Another option would be to "hide" a row/cell. The technique I've used for this is to provide a height of 0 for the given cell via heightForRowAtIndexPath:

like image 183
TomSwift Avatar answered Oct 04 '22 20:10

TomSwift


Like tom said, don't try to "skip" in the UITableViewDelegate methods but instead put this logic in the UITableViewDataSource methods ... As an example, you can set up a common method to filter out your data:

- (NSArray*)tableData {
    NSMutableArray *displayableObjects = [NSMutableArray array];
    [displayableObjects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        CustomObject *customObject = (YourCustomObject *)obj;
        if (customObject.name && ![customObject.name isEqualToString:@""]) {
            // only show in the table if name is populated
            [displayableObjects addObject:customObject];
        }
    }];
    return displayableObjects;
}

and then in your datasource methods, use that to get the pre-filtered data that you want displayed in the table:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [[self tableData] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    CustomObject *o = [[self tableData] objectAtIndex:indexPath.row];
    ....
}

This way whenever reloadData is called it will always skip the filtered data when building the cells.

like image 39
Edwin Iskandar Avatar answered Oct 04 '22 20:10

Edwin Iskandar