Grouped UITableViewCell with transparent background image - iphone

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];

Related

Transparency between UITableViewCells

I want to have transparency between UITableViewCells. Space between the cells.
I user custom created cells and for setting a background i use this code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCell = #"CustomBookingCell";
currentBooking = [arrayBookings objectAtIndex:indexPath.row];
CustomBookingCell *cell = (CustomBookingCell *)[tableView dequeueReusableCellWithIdentifier:CustomCell];
if (cell == nil) {
UIViewController *c = [[UIViewController alloc] initWithNibName:#"CustomBookingCell" bundle:nil];
cell = (CustomBookingCell *)c.view;
[ c release ];
}
bookingImage = [[UIImageView alloc] initWithImage:
[UIImage imageNamed:currentBooking.imageSource]];
[cell.imageForBooking addSubview:bookingImage];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
cell.contentView.backgroundColor = [UIColor clearColor];
UIView* backgroundView = [[UIView alloc] initWithFrame:CGRectZero];
UIImage* bgImage = [UIImage imageNamed:#"Background_300_82.png"];
UIColor *bgColor = [[UIColor alloc] initWithPatternImage: bgImage];
backgroundView.backgroundColor = bgColor;
cell.backgroundView = backgroundView;
cell.label.text = currentBooking.title;
[bookingImage release];
[bgColor release];
[backgroundView release];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 90;
}
The height of the cell is 10 pixels higher that the tableCellBg.png.
My background view has also a image as background (this background is supposed to be shown between the cells of course).
So I tried to add 10 pixels with transparency to my tableCellBg.png in the bottom to fix this. But the space between the cells is black. I can't see the view background between my cells.
What shall I do? Do I have to create a UIView in cellForRowAtIndexPath with the height of the tableCellBg.png and then add the Custom UITableViewCell as subview to the created UIView with a less higher height?
Or is there a much more simplyfied way to accomplish this?
Your table view needs a clear background colour. For example
myTableView.backgroundColor = [UIColor clearColor];
I solved it by using another method to add the background image to the UITableViewCell:
UIImage *image = [UIImage imageNamed:#"ny_bg_event.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(0, 0, 300, 84);
cell.backgroundView = imageView;
cell.backgroundColor = [UIColor clearColor];
[imageView release];
[cell setFrame:CGRectMake(0, 0, 300, 84)];
cell.contentView.backgroundColor = [UIColor clearColor];
Instead of creating a UIView I just used a UIImageView instead.

UITableViewCell background size

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 ;)

Setting background image of custom table view cells

I've tried numerous ways of setting the background image of an unselected table cell, but without success:
1- In IB setting the image field
2- cell.contentView.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"list.png"]];
3- cell.imageView.image = [UIImage imageNamed:#"list_selected.png"];
All seem to fail. The image setting for selected cell works, but not for an unselected cell. Anyone having any idea what might be wrong here?
Thanks
Try setting the backgroundView to an imageView of the image.
Code example from Jason Moore (with TomH's correction):
cell.backgroundView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"foo.png"]] autorelease];
cell.backgroundImage no longer exists. Instead use:
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"foo.png"]];
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html
I've been doing this using the following UITableViewDelegate method, and setting the cell.backgroundColor property. It gets called last, right before the cell is actually drawn on the screen:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row%2)
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"TableCell-BG-Dark.png"]];
else
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"TableCell-BG-Light.png"]];
}
And yes, I'm using a custom subclass of UITableViewCell.
try doing this :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:DateCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:DateCellIdentifier] autorelease]
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"gradient.png"]];
[cell setBackgroundView:img];
[img release];
}
cell.textLabel.text = #"Text";
}
I've also had problems with trying to change the background colour of cells, i ended up subclassing the cell for different reasons, this is my cell background alternation code:
if (indexPath.row % 2 == 0) {
cell.contentView.backgroundColor = [UIColor colorWithWhite:230.0/255 alpha:1];
} else {
cell.contentView.backgroundColor = [UIColor colorWithWhite:242.0/255 alpha:1];
}

Label in UITableViewCell blocking background

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.

How to load images into Custom UITableViewCell?

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];