views:

432

answers:

2

I have a UITableView with custom cells.
I have MyTableViewCell : UITableViewCell and MyTableViewCellContentView : UIView classes.

What I'm doing is basically what is done in the AdvancedTableViewCells demo app from Apple with a slight change, on some rows I want to use a clearColor background to show the table's background behind the painted text.

So in MyTableView's cellForRowAtIndexPath I'm doing:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MyCell";

    MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.someValue = indexPath.section;
    [cell finishedSetup];

    return cell;
}

And in my MyTableViewCell's finishedSetup:

cellContentView = [[MyTableViewCellContentView alloc] initWithFrame:CGRectMake(0, 0, 320, 80) cell:self];
cellContentView.autoresizingMask = UIViewAutoresizingNone;
cellContentView.contentMode = UIViewContentModeRedraw;
[self.contentView addSubview:cellContentView];

And in MyTableViewCellContentView I implement the drawRect method. And plan to not use any subviews but draw my custom content just as the Apple example does in the CompositeSubviewBasedApplication.

The problem is that for a few sections I want to use a clearColor backgroundColor. This works, until a cell with a non-clearColor backgroundColor is reused to draw a clearColor cell, at which time the background is not cleared and will still have the old color.

How can I make the background redraw?

Edit: I forgot to mention, I'm setting the background color in MyTableViewCellContentView's init after calling super's init. Setting it via:

self.backgroundColor = [UIColor clearColor];

I've verified that this in fact does get called and is called as expected with clearColor or redColor.

I've also tried setting the table cell's background color, it didn't help.

Edit #2: Here's my drawRect method:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];
    static int i = 0;
    [[NSString stringWithFormat:@"Cell %d", ++i] drawAtPoint:CGPointMake(3, 3) withFont:[UIFont boldSystemFontOfSize:16]];
}
+1  A: 

To make the background color setting take effect you need to do the setting in tableView:willDisplayCell:forRowAtIndexPath - the OS will not alter anything you set here. The reason is that some additional setup of the cell gets done by the OS after you return it from tableView:cellForRowAtIndexPath. If you can, get a look at session 101 from WWDC 09 presented by Jason Beaver.

Adam Eberbach
I've implemented willDisplayCell, and in it did: `cell.backgroundColor = [UIColor clearColor]; cell.contentView.backgroundColor = [UIColor clearColor];`. Using the debugger I confirmed it was getting called. But it didn't help.
Prody
Are you 100% sure all the subviews of the cell are clear where required also?self.backgroundView.backgroundColor = [UIColor clearColor];self.contentView.backgroundColor = [UIColor clearColor];self.view.backgroundColor = [UIColor clearColor];etc. depending on your cell style
Adam Eberbach
@Adam Eberbach: as mentioned in the post, I don't have other subviews, I'm manually drawing elements in the custom UIView for performance reasons. Currently I'm only drawing a text. But my problem is not that the background is not set to transparent, it is properly set. My problem is that the transparent part is not redrawn when a cell is reused. It's just like using a piece of paper to take notes multiple times.
Prody
btw, just to be clear, if I s/clearColor/whiteColor/g, or any other solid color, everything is fine. But I need to use the clear color for a few sections.
Prody
So I think you are seeing the text (correctly transparent) remaining on the background? (screenshot?) What if you do -setNeedsDisplay further up the view hierarchy?
Adam Eberbach
"I implement the drawRect method"[super drawRect]?
Adam Eberbach
@Adam: I've tried using setNeedsDisplay on the view and on it's parent UITableViewCell, it didn't help. I've also tried adding the [super drawRect] call (both top and bottom), didn't help either.
Prody
A: 

I haven't found out why it was happening. But I've tried a different strategy. I'm no longer reusing table cells, since I don't have that many of them.

Instead I'm creating all cells at startup and actually get a boost in performance when showing them since this way there is no additional setup needed when scrolling.

Prody
Happy to know it works.
Adam Eberbach
If I read your code correctly ( and maybe I'm not ), you are using the same cell identifier when you dequeue. If you have different kinds of cells ( which it sounds like you want? ), you need to use different identifiers when you create and/or dequeue them.
darelf