I'm using a text label with a background as my cell.accessoryView. When the Table gets selected, my accessory view background (label.backgroundColor) disappears. I'm able to restore the label's text color by setting label.highlightedTextColor. But I couldn't restore its background color. Is there something like highlightedTextBackgroundcolor or selectedBackgroundView?
UIImage *indicatorImage = [UIImage imageNamed:DISTANCE_BUBBLE];
cell.accessoryView = [[UIImageView alloc]initWithImage:indicatorImage];
distanceLabel=[[UILabel alloc]initWithFrame:cell.accessoryView.bounds];
distanceLabel.textColor=[UIColor whiteColor];
distanceLabel.textAlignment=UITextAlignmentCenter;
distanceLabel.font=[UIFont boldSystemFontOfSize:13.0];
distanceLabel.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:DISTANCE_BUBBLE]];
distanceLabel.numberOfLines = 0;
distanceLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.accessoryView=distanceLabel;
Subclass UITableViewCell.
It'll give you much more control and keep your cellForRowAtIndexPath method tidier.
Create your accessory view as a view that contains the background in one view and the label.
write Following code may be helpful for you.
////////////////////////////////////////////////////////////////
Edited Code //////////////////////////////////////////////////////////////////////////////
For Display backGroundColor of cell Accessory View
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Foobar"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Foobar"];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.textLabel.textColor = [UIColor blackColor];
}
UIImageView *colorView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
CGRect rect = CGRectMake(0.0f, 0.0f, 30.0f, 30.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
CGContextFillRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[colorView setImage:image];
[cell setAccessoryView:colorView];
cell.textLabel.text=[self.listOfFrnd objectAtIndex:indexPath.row];
return cell;
}
Display Cell BackGround Image of cell Accessory View
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Foobar"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Foobar"];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.textLabel.textColor = [UIColor blackColor];
}
UIImageView *colorView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
CGRect rect = CGRectMake(0.0f, 0.0f, 30.0f, 30.0f);
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [[UIColor redColor] CGColor]);
CGContextFillRect(context, rect);
UIGraphicsEndImageContext();
[colorView setImage:[UIImage imageNamed:#"apple.png"]];
[cell setAccessoryView:colorView];
cell.textLabel.text=[self.listOfFrnd objectAtIndex:indexPath.row];
return cell;
}
After I tried, found that if you take more then one cell accessoryView then it display only one accessoryView. I am not sure that i am right but may be it is true :)
Thanks :)
I'm trying to give the cells in my grouped UITableView a semi-transparent image as their background. I've tried so many different ways but can't seem to get it to work. This is what I've got so far:
-(void) viewWillAppear:(BOOL) animated{
[super viewWillAppear:animated];
self.table.backgroundColor = [UIColor clearColor];}
.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UIImage *cellBackground;
NSInteger sectionRows = [tableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0)
{
cellBackground = [UIImage imageNamed:#"tCT.png"];
}
else if (row == sectionRows -1)
{
cellBackground = [UIImage imageNamed:#"tableCellBottom.png"];
}
else
{
cellBackground = [UIImage imageNamed:#"tableCellMiddle.png"];
}
cell.backgroundColor = [UIColor clearColor];
UIView *cellBackView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
cellBackView.backgroundColor = [UIColor colorWithPatternImage: cellBackground];
cell.backgroundView = cellBackView;
So at the moment the image shows up, but it's transparency isn't obvious. The background is a solid grey (rather than a semi-transparent grey). There are also black corners on the rounded group-table corners.
Any idea where I'm going wrong?
set the backgroundColor of your cell's contentView to clearColor to remove the black borders.
self.contentView.backgroundColor = [UIColor clearColor];
I'm trying to set the size of my background to be a little shorter than the default, creating some space between the cells. This has proven to be difficult. Setting the frame of the background view seems to do nothing:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *reuseIdentifier = #"cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell)
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:reuseIdentifier] autorelease];
// Set up the cell...
cell.contentView.backgroundColor = [UIColor clearColor];
cell.backgroundView = [[[UIView alloc] initWithFrame:CGRectMake(0, 4, 320, 42)] autorelease];
cell.backgroundView.backgroundColor = [UIColor blackColor];
cell.backgroundView.alpha = .2;
cell.selectedBackgroundView = [[[UIView alloc] initWithFrame:CGRectMake(0, 4, 320, 42)] autorelease];
cell.selectedBackgroundView.backgroundColor = [UIColor whiteColor];
cell.selectedBackgroundView.alpha = .2;
cell.font = [UIFont fontWithName:#"MarkerFelt-Thin" size:22.0f];
cell.selectedTextColor = [UIColor blackColor];
cell.textColor = [UIColor whiteColor];
NSDictionary *dict = [files objectAtIndex:indexPath.row];
cell.text = [dict objectForKey:#"name"];
return cell;
}
Any help?
Also, setting the selected background view doesn't do anything. When a cell is selected, the background is completely blank. Why is this?
I'm using iPhone OS 2.2.1.
I also do this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.rowHeight = 50.0f;
}
You can download the code here (made a small project for this issue only):
http://dl.dropbox.com/u/608462/tabletest2.zip
The backgroundView is not a normal view, there's something going on behind the scenes. Check this link out:
Difference between background view and content view in uitableviewcell
Specifically, from the documentation:
backgroundView:
The default is nil for cells in plain-style tables (UITableViewStylePlain) and non-nil for grouped-style tables UITableViewStyleGrouped). UITableViewCell adds the background view as a subview behind all other views and uses its current frame location.
Hence: it doesn't really have a frame location, it uses the cell's frame location.
This code worked:
UIImageView *bgView = [[UIImageView alloc] init]; // Creating a view for the background...this seems to be required.
bgView.backgroundColor = [UIColor redColor];
cell.backgroundView = bgView;
UIImageView *bgImageView = [[UIImageView alloc] init]; // Creating a subview for the background...
bgImageView.backgroundColor = [UIColor colorWithWhite:1 alpha:1];
[bgImageView setFrame:CGRectInset(cell.bounds, 1, 1)];
[cell.backgroundView addSubview:bgImageView]; // Assigning the subview, and cleanup.
[bgImageView release];
[bgView release];
Spent about an hour trying to figure this out...but it works. This is code in the cellForRowAtIndexPath delegate method--I won't cover the whole thing here obviously.
morgancodes' solution led me into the right direction.
I added a sublayer to the background view and styled it. When setting the background color of the background view to clearColor, the sublayer is the only thing showing.
UIView *backgroundView = [[UIView alloc] init];
backgroundView.backgroundColor = [UIColor clearColor];
CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor colorWithWhite:1 alpha:0.8].CGColor;
sublayer.frame = CGRectMake(15, 3, tableView.frame.size.width - 45, 38);
sublayer.cornerRadius = 5;
[backgroundView.layer addSublayer:sublayer];
cell.selectedBackgroundView = backgroundView;
Here's a completely different method from what you're trying.
One thing I like to do is use a custom image for the backgroundView and selectedBackgroundView, rather than let the iPhone handle the coloring tasks. This gives me a lot more flexibility on how the cell is rendered. All it takes is adding something like this:
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"normal.png"]];
cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"selected.png"]];
To:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
Yet another approach: add a sublayer to your background. I added the following to the initialization of a UITableViewCell subclass and it seems to work great.
UIView* backgroundView = [[UIView alloc] initWithFrame: self.contentView.frame ];
backgroundView.layer.frame = CGRectInset(backgroundView.layer.frame, 20, 20);
CALayer *sublayer = [CALayer layer];
sublayer.backgroundColor = [UIColor colorWithWhite:0.69 alpha:1].CGColor;
sublayer.frame = CGRectMake(INDENT, 0, width - (INDENT * 2), [ChuckWagonTableViewCellCell cellHeight]) ;
[backgroundView.layer addSublayer:sublayer];
self.selectedBackgroundView = backgroundView;
Try this:
UIView *bg = [[UIView alloc] initWithFrame: CGRectInset(cell.frame, 0.0, 2.0)];
bg.backgroundColor = [UIColor whiteColor];
cell.backgroundView = bg;
Also don't forget to set background color and separator color to clear in viewDidLoad():
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.separatorColor = [UIColor clearColor];
self.tableView.backgroundColor = [UIColor clearColor];
}
When messing with the background view, I would do it in:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
rather than in:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
Try using:
cell.backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 4.0, 320.0, 40.0)]];
For the second question, did you implement:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
What i think is happening, is that when you select a row, internally the selectedbackgroundview's alpha value is se to 1, thus showing it completely white.
I had a similar problem, and none of the answers seemed to fit in my case.
All my rows have the same height in this case, but with some math this could be adapted to accomodate rows with different heights.
I had set the height in my controller, by using the UITableViewDelegate method. I have an instance variable called cellBackgroundImage on my controller that is the UIImage that will be used for the UITableViewCell background. The UITableView background is set to [UIColor clearColor].
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return cellBackgroundImage.size.height + SPACING_HEIGHT;
}
Where SPACING_HEIGHT is a #define constant for the gap height.
Then, the trick was to use an UIView that would wrap the UIImageView that will be the cell's background. I accomplished this by doing:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ContentCell"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"ContentCell"] autorelease];
CGFloat height = [self tableView:tableView heightForRowAtIndexPath:indexPath];
cell.frame = CGRectMake(0, 0, [UIScreen mainScreen].applicationFrame.size.width, height);
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIView *backView = [[UIView alloc] initWithFrame:CGRectInset(cell.frame, 0, 0)];
UIImageView *imageView = [[UIImageView alloc] initWithImage:cellBackgroundImage];
[backView insertSubview:imageView atIndex:0];
cell.backgroundView = backView;
[backView release];
[imageView release];
}
return cell;
}
Then, by setting cell.backgroundView = backView to the UIView with the UIImageView that contains my background, i managed to achieve the gap effect between rows.
I hope this helps.
A possible solution could be to subclass UIView and add color and height arguments (if you only want to change the height, otherwise you can pass a size/rect). Note that a background color needs to be set, otherwise you'll see a blank area.
- (id)initWithColor:(UIColor *)color height:(CGFloat)height backgroundColor:(UIColor *)backgroundColor;
{
self = [super init];
if (self != nil)
{
_color = color;
_height = height;
_backgroundColor = backgroundColor;
}
return self;
}
Add the appropriate properties:
#interface CellSelectedBackgroundView ()
#property (strong, nonatomic) UIColor *color;
#property (strong, nonatomic) UIColor *backgroundColor;
#property (assign, nonatomic) CGFloat height;
#end
And in drawRect: you can fill the area:
- (void)drawRect:(CGRect)rect
{
[self.backgroundColor setFill];
UIRectFill(rect);
[self.color setFill];
CGRect frame = CGRectMake(0, 0, self.bounds.size.width, self.height);
UIRectFill(frame);
}
Simply initialize you custom UIView subclass and set it as the selectedBackgroundView property of your UITableViewCell.
Try adding a subview into your backgroundViews instead of modifying them directly:
UIView *selectedView = [[UIView alloc] initWithFrame:UIEdgeInsetsInsetRect(cell.frame, UIEdgeInsetsMake(8, 8, 8, 8))];
selectedView.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView = [UIView new];
cell.selectedBackgroundView.backgroundColor = [UIColor clearColor];
[cell.selectedBackgroundView addSubview:selectedView];
I had the same problem as yours with the selectedBackgroundView and this worked for me ;)
I'm having an issue with the label inside of my UITableViewCell blocking the background image. It seems as though it only happens on the unselected state. I tried setting the background colors to clear but that didn't do it. It's adopting the tableview's background color. Do I have to set the labels background image too?
// Neither of these worked...
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
Here is my cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SimpleTableIdentifier"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"SimpleTableIdentifier"] autorelease];
}
UIImage *image = [UIImage imageNamed:#"TableRow.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.contentMode = UIViewContentModeScaleToFill;
cell.backgroundView = imageView;
[imageView release];
UIImage *imageSelected = [UIImage imageNamed:#"TableRowSelected.png"];
UIImageView *imageViewSelected = [[UIImageView alloc] initWithImage:imageSelected];
imageViewSelected.contentMode = UIViewContentModeScaleToFill;
cell.selectedBackgroundView = imageViewSelected;
[imageViewSelected release];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = [[self.trivia.questionsets objectAtIndex:indexPath.row] valueForKeyPath:#"title"];
return cell;
}
UPDATE: Kinda resolved...
If i set the background color of the table (which I assumed would be beneath everything) to clear, then all of a sudden my image shows where i expect, but the table background now shows over top of everything? Is this the expected behavior? (Haven't checked the docs on this yet)
tableView.backgroundColor = [UIColor redColor];
cell.contentView.backgroundColor = [UIColor orangeColor];
cell.textLabel.backgroundColor = [UIColor yellowColor];
...and to finish, if I set both the table and cell's background colors to clear, we're good. the textlabel background color makes no difference.
tableView.backgroundColor = [UIColor clearColor];
cell.contentView.backgroundColor = [UIColor clearColor];
cell.textLabel.backgroundColor = [UIColor yellowColor];
Yeah it is expected behaviour.
Your tableview is a subview that sits in front of everything else. If something was in front of the tableview (ie the background), it would obscure the table.
Here's what I need to do:
Load 66px x 66px images into the table cells in the MainViewController table.
each TableCell has a unique image.
But how? Would we use cell.image?
cell.image = [UIImage imageNamed:#"image.png"];
If so, where? Is an if/else statement required?
To load each cell's labels, MainViewController uses an NSDictionary and NSLocalizedString like so:
//cell one
menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(#"PageOneTitle", #""), kTitleKey,
NSLocalizedString(#"PageOneExplain", #""), kExplainKey, nil]];
//cell two
menuList addObject:[NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(#"PageOneTitle", #""), kTitleKey,
NSLocalizedString(#"PageOneExplain", #""), kExplainKey, nil]];
...
// this is where MainViewController loads the cell content
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = (MyCustomCell*)[tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil)
{
cell = [[[MyCustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:kCellIdentifier] autorelease];
}
...
// MyCustomCell.m adds the subviews
- (id)initWithFrame:(CGRect)aRect reuseIdentifier:(NSString *)identifier
{
self = [super initWithFrame:aRect reuseIdentifier:identifier];
if (self)
{
// you can do this here specifically or at the table level for all cells
self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Create label views to contain the various pieces of text that make up the cell.
// Add these as subviews.
nameLabel = [[UILabel alloc] initWithFrame:CGRectZero]; // layoutSubViews will decide the final frame
nameLabel.backgroundColor = [UIColor clearColor];
nameLabel.opaque = NO;
nameLabel.textColor = [UIColor blackColor];
nameLabel.highlightedTextColor = [UIColor whiteColor];
nameLabel.font = [UIFont boldSystemFontOfSize:18];
[self.contentView addSubview:nameLabel];
explainLabel = [[UILabel alloc] initWithFrame:CGRectZero]; // layoutSubViews will decide the final frame
explainLabel.backgroundColor = [UIColor clearColor];
explainLabel.opaque = NO;
explainLabel.textColor = [UIColor grayColor];
explainLabel.highlightedTextColor = [UIColor whiteColor];
explainLabel.font = [UIFont systemFontOfSize:14];
[self.contentView addSubview:explainLabel];
//added to mark where the thumbnail image should go
imageView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 66, 66)];
[self.contentView addSubview:imageView];
}
return self;
}
If the image is going to be the same for every cell, i.e., it's part of that type of cell, you could load it in MyCustomCell's init, using self.image = [UIImage imageNamed:"blabla"];
Otherwise, if the image will be different for different cells, it would be more logical to put it in tableView:cellForRowAtIndexPath:
Yes, cell.image is deprecated. use imageview.image instead in the default TableViewCell. I am not sure why custom cell was required to do what the standard tableviewcell already does (title, subtitle, and an image using UITableViewStyleSubtitle)
It works now. You were right, Seventoes, about putting it in tableView:cellForRowAtIndexPath:
indexPath.row was what I was I missing. The working result goes like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = (MyCustomCell*)[tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil)
{
cell = [[[MyCustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:kCellIdentifier] autorelease];
}
if (indexPath.row == 1)
{
cell.image = [UIImage imageNamed:#"foo.png"];
}
else if (indexPath.row == 2)
cell.image = [UIImage imageNamed:#"bar.png"];
}
...
else
{
cell.image = [UIImage imageNamed:#"lorem.png"];
}
return.cell;
}
A better approach then that if-else mess would be to push your images onto a NSMutableArray in the right order, and then just use
cell.image = [myImages objectAtIndex:indexPath.row];