I have a uitableview with 2 rows n 4 sections and i have a label and textfield in each cells. And the problems is my label comes in all section where as my textfield is not repeating in other sections. Actually i have two textfield one for each cell, one is normal textfield and another is picker textfield (when I clicked TF the picker will pop up). For one section both the TF coming but it's not repeating in other section.
My code
static NSString *CellIdentifier = #"Cell";
UITextField *textField;
NSString *string=[NSString stringWithFormat:#"ident_%d",indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:string];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
UILabel *lbl1 = [[UILabel alloc]initWithFrame:CGRectMake(50, 10, 100, 35)];
[lbl1 setFont:[UIFont systemFontOfSize:16]];
[lbl1 setTextColor:[UIColor blackColor]];
[lbl1 setBackgroundColor:[UIColor clearColor]];
if (indexPath.row==0) {
lbl1.text = #"Quantity";
[cell.contentView addSubview:self.qntTF];
}
if (indexPath.row==1) {
lbl1.text = #"Unit";
[cell.contentView addSubview:self.unitTF];
}
// Configure the cell...;
textField =[self.tableArray objectAtIndex:indexPath.row];
[cell.contentView addSubview:textField];
cell.textLabel.text = nil;
textField.tag = TextFieldTag;
cell.detailTextLabel.text = nil;
[cell addSubview:lbl1];
[lbl1 release];
return cell;
The way the code is now, you're adding many, many more labels than you think (each time the table scrolls) and you're only adding one text field, then moving it around to different cells. It ends up on whichever cell was rendered last.
The way your cellForRow... method is now, every time row 0 and 1 for any section appears - including when the user is just scrolling them on and off the screen - another text view and label are added as subviews to the cell. Scroll up and down 100 times, there will be 100 text views and labels stacked one on top of another in the cell.
To avoid this, only add subviews when the cell is created. So in this block...
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *label = /* all of your label init */
label.tag = kSOME_UNIQUE_INT_CONST;
UITextField *textField = /* all of your text field init */
textField.tag = kSOME_OTHER_UNIQUE_INT_CONST
[cell addSubview:label];
[cell addSubview:textField];
}
Now, after the block, you can assume that each cell you has exactly one label and one textField. The next job is to find them (they were either just created, or already in the cell if it was reused)...
UILabel *label = (UILabel *)[cell viewWithTag:kSOME_UNIQUE_INT_CONST];
UILabel *textField = (UITextField *)[cell viewWithTag:kSOME_OTHER_UNIQUE_INT_CONST];
Now you're ready to configure the cell for the given section and row. The key here is to remember that you're often getting reused cells. They will still be configured for rows that have been scrolled away. So every "if" block needs a corresponding "else" block to change the subviews' states:
if (indexPath.row == 0) {
label.text = #"Quantity";
// not sure what view you were adding here, but don't
// subview adds only in the cell==nil block above
} else {
label.text = /* whatever the label should be for row != 0 */
// this is important: if you change label state in the if, you
// must specify it's state also in an else, otherwise you'll see
// leftover state on the label when the cell is reused for a different row
}
Why don't you initialise the text box the same way you do the label?
You have for the TextField:
UITextField *textField;
Then The Label:
UILabel *lbl1 = [[UILabel alloc]initWithFrame:CGRectMake(50, 10, 100, 35)];
[lbl1 setFont:[UIFont systemFontOfSize:16]];
[lbl1 setTextColor:[UIColor blackColor]];
[lbl1 setBackgroundColor:[UIColor clearColor]];
Why don't you try this near the label:
UITextField *textfield = [[UITextField alloc]initWithFrame:CGRectMake(LOCATION)];
[textfield setTextColor:[UIColor blackColor]];
[textfield setBackgroundColor:[UIColor clearColor]];
[textfield setBorderStyle:UITextBorderStyleNone];
Also it could be that your array you get your textfields from only has two textfields in it?
Also it could be because it looks like you are not instancing a new text box just adding the same one from the implementation over and over again, Example:
if (indexPath.row==0) {
lbl1.text = #"Quantity";
[cell.contentView addSubview:self.qntTF];
}
if (indexPath.row==1) {
lbl1.text = #"Unit";
[cell.contentView addSubview:self.unitTF];
}
before return the cell add [cell setNeedsDisplay]; line.
[cell setNeedsDisplay];
return cell;
it will be ok.
thanx.
Related
I'm having a weird problem with my cells when it gets highlighted.
Just to introduce you better what the problem is, take a look at these two pictures:
This is how the cell looks like when it's not selected (normal state): http://cl.ly/0n193u3U1o403x1s0m3z
This is how the cell looks when it's highlighted (during tap): http://cl.ly/1o2U400D3L0b3n3m1N1J
As you can see, the background of the second label seems to get ignored when the cell is selected.
I don't want this to happen. I just want the 2nd label to stay there and remain as it is.
This is how I create the cells (there are several types each of them using different cell identifier).
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellTableIdentifier] autorelease];
cell.backgroundView = [[[UIView alloc] init] autorelease];
}
switch (indexPath.section) {
...
...
case kTableSectionPending:
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(10, 10, self.tableView.frame.size.width - 20, 30.0)] autorelease];
UILabel *label2 = [[[UILabel alloc] initWithFrame:CGRectMake(10, 50, self.tableView.frame.size.width - 20, 30.0)] autorelease];
label.text = NSLocalizedString(#"IncompletePath", #"");
label.font = [UIFont boldSystemFontOfSize:16];
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
label.layer.cornerRadius = 10;
FFRoute *lastPoint = ((FFRoute *) [[[FFSQLite sharedSingleton] getRoutesFromItinerary:itinerary] lastObject]);
label2.text = [NSString stringWithFormat:#"%#: %#", NSLocalizedString(#"LastPoint", #""), [self getStringFromTimestampOfFFRoute:lastPoint]];
label2.font = [UIFont systemFontOfSize:15];
label2.textAlignment = UITextAlignmentCenter;
label2.textColor = [UIColor whiteColor];
label2.backgroundColor = [UIColor colorWithRed:68/255.f green:82/255.f blue:124/255.f alpha:1];
label2.layer.cornerRadius = 10;
[label2 setOpaque:YES];
[cell.contentView addSubview:label];
[cell.contentView addSubview:label2];
// Set up background color
UIColor *bgcolor = [UIColor colorWithRed:250/255.f green:212/255.f blue:137/255.f alpha:1];
cell.backgroundView.backgroundColor = bgcolor;
break;
}
I tried to set to true the Opaque property with no luck.
What am I missing? Thank you
When you create the cell, do:
cell.selectionStyle = UITableViewCellSelectionStyleNone;
A cell can be highlighted, selected or both. You might want to customize your drawing so that it draws in a selected state (but draws as usual when only in highlighted state).
In iOS 6, you can use 2 methods in UITableViewDelegate to customise highlighting for the cell, and also its subviews:
- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundColor:[UIColor lightGrayColor]]; // Your highlight color
// Make changes to subviews in cell
}
- (void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[UIView animateWithDuration:0.5f animations:^{
[cell setBackgroundColor:[UIColor whiteColor]]; // Your unhighlight
// Revert back changes for subviews
}];
}
In my cellForRowAtIndexPath, I'm doing some custom formatting on a subview for when that cell is selected. The complete function is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIView *left;
UIImageView *leftImage;
UILabel *label;
ArticleButton *btn;
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (!cell)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:#"UITableViewCell"] autorelease];
left = [[[UIView alloc] initWithFrame:CGRectMake(0, 2, 155, 139)] autorelease];
leftImage = [[[UIImageView alloc] initWithFrame:CGRectMake(7,9,141,77)] autorelease];
label = [[[UILabel alloc] initWithFrame:CGRectMake(6,87,141,48)] autorelease];
btn = [[[ArticleButton alloc] initWithFrame:CGRectMake(0,2,155,139)] autorelease];
left.tag = 0;
leftImage.tag = 1;
label.tag = 2;
btn.tag = 3;
[btn addTarget:self action:#selector(selectArticle:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:left];
[cell.contentView addSubview:leftImage];
[cell.contentView addSubview:label];
[cell.contentView addSubview:btn];
}
else
{
left = (UIView*)[cell viewWithTag:0];
leftImage = (UIImageView*)[cell viewWithTag:1];
label = (UILabel*)[cell viewWithTag:2];
btn = (ArticleButton*)[cell viewWithTag:3];
}
...load *entry
NSURL *url = [NSURL URLWithString:[entry imageUrl]];
FeedEntry* selectedEntry = [detailViewController detailItem];
NSString* selectedTitle = selectedEntry.title;
if ([selectedTitle isEqualToString:entry.title])
{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground_sel.png"]]]; <-- PROBLEM IS THIS IMAGE NEVER CHANGES
NSLog(#"selected row %#", selectedTitle);
}
else{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground2.png"]]];
}
[left setNeedsDisplay];
[leftImage setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder.gif"]];
[leftImage setContentMode:UIViewContentModeScaleAspectFill];
leftImage.clipsToBounds = YES;
[label setBackgroundColor:[UIColor clearColor]];
label.textColor = [UIColor whiteColor];
label.text = [entry.title stringByAppendingString:#"\n\n"];
label.numberOfLines = 3;
label.lineBreakMode = UILineBreakModeClip;
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:12];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
The problem I'm having is with this section:
if ([selectedTitle isEqualToString:entry.title])
{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground_sel.png"]]];
NSLog(#"selected row %#", selectedTitle);
}
else{
[left setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cellbackground2.png"]]];
}
Everything else works, but although I'm logging that it gets called, but the background of my subview to indicate that the row in question is a selected row, never changes. I've tried calling setNeedsDisplay, I've tried scrolling up and down trying to get the cells to dequeue and get recreated, it just never users the other image, even though it logs that the row being drawn was a selected row.
(Once I get this working, I need to implement the "right" section to have two "cells" in the one row and only one will be selected. That's why I'm doing it this way with subviews in the cell).
What am I doing wrong?
I think it is a problem to set the tag to zero. The documentation says:
viewWithTag:
Return Value
The view in the receiver’s hierarchy whose tag property matches the value in the tag parameter.
Discussion
This method searches the current view and all of its subviews for the specified view.
If think that most views tag is zero, even that of the current cell's view. I think that you dont get the correct view out of it. Try not to use 0 as a tag to work with.
Whenever a particular UITableViewCell is selected, this particular delegate is called -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Try to see if your button taps are being first responded by this delegate rather than going to selectArticle: selector you have defined...
Instead of setting this in tableview:cellForRowAtIndexPath:, try doing it in the tableview:willSelectRowAtIndexPath:
See the protocol reference for further details.
I have this code below to populate my UITableView on the fly.
I have to display two kind of cells: a regular cell with a background image and a cell with a regular background image, plus a label and a button.
if Indexpath.row is less than a control variable, then regular cells are drawn. If not, cells with buttons and labels are drawn.
this is the code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
UIImage *imageU;
if (indexPath.row < controlVariable) {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table%d", indexPath.row] ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
} else {
imageU = [[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:[NSString stringWithFormat: #"table-pg%d",numberX]
ofType:#"jpg"]] autorelease];
cell.imageView.image = imageU;
NSString * myString = [NSString stringWithFormat: #"pago%d", numberX];
UILabel * myLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 49.0, 200.0, 22.0)];
[myLabel setTextAlignment:UITextAlignmentLeft];
[myLabel setBackgroundColor:[UIColor blueColor]];
[myLabel setClipsToBounds:YES];
[myLabel setFont:[UIFont systemFontOfSize:14.0]];
[myLabel setTextColor:[UIColor blackColor]];
[myLabel setText: myString];
[myLabel setAlpha:0.6];
[cell addSubview: myLabel];
[myLabel release];
UIButton *buyButton = [[UIButton alloc] initWithFrame:CGRectMake( 220, 4, 100, 35)];
buyButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
buyButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[buyButton setTitle:NSLocalizedString(#"buyKey", #"") forState:UIControlStateNormal];
[buyButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
buyButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
UIImage *newImage = [[[[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]
pathForResource: #"whiteButton" ofType:#"png"]] autorelease]
stretchableImageWithLeftCapWidth:12.0f topCapHeight:0.0f];
[buyButton setBackgroundImage:newImage forState:UIControlStateNormal];
[buyButton addTarget:self action:#selector(comprar:) forControlEvents:UIControlEventTouchDown];
buyButton.backgroundColor = [UIColor clearColor];
[buyButton setTag:indexPath.row];
[cell addSubview:buyButton];
[buyButton release];
}
return cell;
}
The problem with this code is: when I scroll the UITableView down and reach the division between regular cells and cells with buttons and labels, I see it is rendering correctly, but if I go up after going deep down, I see the buttons and labels being added to cells that were not supposed to have them. From this point forward, all cells contains buttons and labels...
It is like the cells are not releasing its contents before drawing. It is like labels and buttons are being added on top of other buttons and labels already on the cell. Cells are not releasing its contents before drawing again.
How to solve that?
thanks for any help.
NOTE: I see barely no difference after making the changes suggested by the two first answers. Now, not all cells are wrong, just some. They change every time I scroll down the table and return to the beginning of the table.
You should use a separate reuseIdentifier for each cell 'type' that you are using. In this case, you'll want to use two.
You'll also want to create/add the UILabel and UIButton when you get a dequeue miss and not for every run through.. In pseudocode:
UILabel * lbl;
UIButton * btn;
cell = [table dequeueReusableCellWithIdentifier:correctIdentifier];
if (cell == nil)
{
cell = ...; // alloc cell
lbl = ...;
lbl.tag = kTagLabel;
[cell addSubView:lbl];
btn = ...;
btn.tag = kTagButton;
[cell addSubView:btn];
}
else
{
lbl = (UILabel*)[cell viewWithTag:kTagLabel];
btn = (UIButton*)[cell viewWithTag:kTagButton];
}
//... now set the text/image appropriately.
Otherwise, you create a label and button each time the cell is dequeued from the table. Scrolling up and down will cause lots of labels and buttons to be created that never get released.
You should use two different reuseIdentifiers; one for cells with just images, and one for cells with images and buttons. The problem is that your one cell type is being reused, but its content is not (nor should it be) cleared out when it's dequeued.
I have found some posts which are similar to my issue but not quite the same.
In my app the user can navigate between several uitableviews to drill down to the desired result. When a user goes forward, then backward, then forward, etc it is noticeable that the rows are being redrawn/re-written and the text gets bolder and bolder.
I have found that in some of the posts this may relate to the way that I am creating the rows, using a uilable within the cellforrowatindexpath method.
Is there something that I need to do so that the rows are not repopulate/redrawn each time a user goes forward and backward between the tableviews? Do I need to add something to the code below or add something to the viewwillappear method (currently there is a 'reloaddata' in the viewwillappear for the table but doesn't seem to help)?
Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
UILabel *label = [[[UILabel alloc] init] autorelease];
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:20];
label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f);
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
label.text = [mapareaArray objectAtIndex:indexPath.row];
[cell.contentView addSubview:label];
CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero];
bgView.borderColor = [UIColor clearColor];
bgView.fillColor = [UIColor whiteColor];
bgView.position = CustomCellBackgroundViewPositionSingle;
cell.backgroundView = bgView;
return cell;
}
The problem you are having is due to this line:
[cell.contentView addSubview:label];
You are adding a subview to the table cell whether it's a new cell or not. If it's an old cell (dequeued from the reusable pool), then you will add yet another subview to the cell.
Instead, you should tag the UILabel, and then locate it with the tag to modify the content of that UILabel. Add (and set all of its attributes) and tag the UILabel inside the if( cell == nil ) block:
if(cell == nil) {
// alloc and init the cell view...
UILabel *label = [[[UILabel alloc] init] autorelease];
label.tag = kMyTag; // define kMyTag in your header file using #define
// and other label customizations
[cell.contentView addSubview:label]; // addSubview here and only here
...
}
Then locate it with:
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag];
label.text = [mapareaArray objectAtIndex:indexPath.row];
And no need to re-add it as a subview outside of the if(cell == nil) block. The subview is already there (and that's why reusing the cell views are so much more efficient, if you do it correctly, that is ;).
.h file
The 'define' is put after the #import statements at top of header file, and was put as 0 because I don't know how else to define it:
#define kMyTag 0
.m file
I have updated this section as per your comments, but a) the table is not populated, b) when the user has navigated to the next view and goes back to this view it fails with a "unrecognized selector sent to instance", and c) I had to put in the two 'return cell;' entries or it falls over. I think I have things in the wrong order and maybe didn't initialise things properly????
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UILabel *label = [[[UILabel alloc] init] autorelease];
label.tag = kMyTag; // define kMyTag in your header file using #define
label.font = [UIFont fontWithName:#"Arial-BoldMT" size:20];
label.frame = CGRectMake(10.0f, 10.0f, 220.0f, 22.0f);
label.textColor = [UIColor blackColor];
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
CustomCellBackgroundView *bgView = [[CustomCellBackgroundView alloc] initWithFrame:CGRectZero];
bgView.borderColor = [UIColor clearColor];
bgView.fillColor = [UIColor whiteColor];
bgView.position = CustomCellBackgroundViewPositionSingle;
cell.backgroundView = bgView;
[cell.contentView addSubview:label]; // addSubview here and only here
return cell;
}
UILabel *label = (UILabel *)[cell.contentView viewWithTag: kMyTag];
label.text = [mapareaArray objectAtIndex:indexPath.row];
return cell;
}
You should create a subclass for UITableViewCell for that specific cell, then apply the logic to see if you need to add the subview to itself every time. Also, use the UITableviewcell's prepareForReuse and remove any subviews during that time before applying the logic of wether you want to add a UILabel to your Cell.
I've got an annoying problem in my tableview. I was able to achive color-changing cells (blue/white/blue/...), but now I'm in trouble with my text, which has a white background on the blue cells.
I've tried for testing to set a background color to red:
// try to set the backgroundcolor of the text ???
cell.textLabel.text.backgroundColor = [UIColor redColor];
which doesn't work; hmph.
Please have a look at my code below; can anybody tell me what's wrong and how I can solve my problem by giving the text a transparent background?
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell
cell.textLabel.text=[RssFeedNodes objectAtIndex:indexPath.row];
// try to set the backgroundcolor of the text ???
cell.textLabel.text.backgroundColor = [UIColor redColor];
// show image in cell
NSString *imageName=#"rss.png";
cell.imageView.image=[UIImage imageNamed:imageName];
// changing colors in cells
NSInteger row = [indexPath row];
if (row % 2){
cell.contentView.backgroundColor = [UIColor whiteColor];
}
else {
cell.contentView.backgroundColor = [UIColor colorWithRed:0.90f green:0.95f blue:1.0f alpha:1.0f];
}
return cell;
}
Your answer is found (and described very well) here: http://undefinedvalue.com/2009/11/02/easy-gradient-backgrounds-uitextviewcells
My brief summary of the solution: Subclass the UITableViewCell, and then use your subclass when creating instances in cellForRowAtIndexPath.
You then need to override just one method (setSelected) in your subclass UITableViewCell:
(void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
for (UIView *view in self.contentView.subviews) {
view.backgroundColor = [UIColor clearColor];
}
}
The reason appears to be that the built-in UITableViewCell class will set the label background to white (or selected color) when being displayed based on the selection state in the table in the setSelected method. Substitute your own, call the base class implementation, then set your subview backgrounds to clear in order to let your contentView background shine through.
text has no background, but textLabel has. so
[[cell textLabel] setBackground:[UIColor redColor]];
You'll need to add your own UILabel label onto the cell, and set the background colour of that to transparent. For some reason the label that a table cell has does not have a settable background colour.
Something like:
UILabel* label = [[UILabel alloc] init];
label.frame = CGRectMake( 20, 10, 200, 22 );
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
label.text = #"your text here:";
[cell addSubview:label];
[label release];
In this example I've set the frame for the label fairly arbitrarily (well not, actually, this was modified from some of my own real code). You may need to be more dynamic with the sizing, in which case you'll probably need to subclass the cell and override setFrame to keep the label's frame in sync. But hardcoded values should get you going for now.
#define LABEL_TAG 99
// whatever your label rect size should be... change as appropriate
UIlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300.0, 30.0)];
label.tag = LABEL_TAG;
// set up alignment, font, autoresizemask, etc.
label.backgroundColor = [UIColor clearColor];
label.opaque = NO;
[cell.contentView addSubview:label];
[label release];
Something to watch out for is that you're not adding your own label to a reuseable table cell more than once. By setting a known view.tag property you can get at (or discover existence of) the UILabel view. [cell viewWithTag:LABEL_TAG]
Whenever you dequeue a reuseable cell, first get the reference to your label view, then do what you would normally do if you were using the UITableCell's textLabel.