views:

616

answers:

1

Hi everyone.

Here is the deal: I have a UITableView with 2 sections, and I want to display a "no data" cell when the first section is empty, so that the 2 section headers are not stuck together (cause it looks weird).

It works great (even though I had trouble making it work at first, see this thread). I'm using viewForFooterInSection :

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {

if(section == 0)
{
        if([firstSectionArray count] == 0)
                return 40;
        else 
                return 0;
}

return 0;

}

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{

    if(section == 0)
    {
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(200, 10, 50, 44)];
        label.backgroundColor = [UIColor clearColor];
        label.textColor = [UIColor colorWithWhite:0.6 alpha:1.0];
        label.textAlignment = UITextAlignmentCenter;
        label.lineBreakMode = UILineBreakModeWordWrap; 
        label.numberOfLines = 0;
        label.text = @"No row";
        return [label autorelease];
    }

    return nil;
}

But the background color turns plain white when I display the section footer view. See image:

alt text

I like it better when the background is filled with empty cells. Does anyone have any idea how to do that? Thanks

+1  A: 

The background is filled with empty cells when you have no footer. So do not implement a viewForFooterInSection (or titleForFooterInSection) method, and you will get the "empty cells" effect.

I'd recommend that you return a cell indicating that there are no entries to show, like so:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (matches.count>0) {
        // Do your usual thing here
    } else {
        static NSString *cellId = @"noDataCell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId] autorelease];
            cell.textLabel.textAlignment = UITextAlignmentCenter;
            cell.textLabel.textColor = [UIColor grayColor];
        }
        cell.textLabel.text = @"Aucun match";
        return cell;
    }
}

And of course, you would have to tell UIKit that you always have at least one cell in your section... I've added the isDeletingRow case that seems to trouble you (in comment).

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section==0) return matches.count>0 ? matches.count : (isDeletingRow ? 0 : 1);
    // Set 'isDeletingRow' to YES when a delete is being committed to the table, in that case we let UIKit know that we indeed took care of the delete...
    // And cover the other sections too...
}

When you are committing the edits, you need to set isDeletingRow for numberOfRowsInSection to return a satisfactory value...

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        isDeletingRow = YES;
        // Your current code when a row is deleted here...
        isDeletingRow = NO;
        if (matches.count==0) [self.tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.5];
    }
}
Zoran Simic
I already tried that, but I get an NSInternalInconsistencyException when I delete the last row of the section : 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'This is driving me crazy!!
Supernico
I've updated the answer to show you how you can take care of that problem :) You indeed need to go to a row count of 0 for the section, but there's away to make that work too...
Zoran Simic
Thank you so much Zoran! It works! (though still a little bit hacky, but I guess we don't have a choice here...)
Supernico
I didn't find a better way :) UIKit is right to check that a row was indeed removed... but here you really want the last row replaced by the "Aucun match" row, while using the 'delete' feature... it has to be a bit hacky, since we're hijacking the 'delete' to be used as a 'replace' really... :)
Zoran Simic
I guess you're right :)But I liked the viewForFooterInSection solution better, it's a shame we can't avoid the annoying white background!
Supernico
Yup, it's too bad :) My guess is that the footer is rendered last, hiding the "empty cells" that you see when there's no footer...
Zoran Simic