UITableViewCell background size - iphone

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

Related

UITableView performance issues when adding UIViews to cell.contentView

I am experiencing performance problems when using some subviews on my UITableViewCells. After I keep scrolling it eventually starts getting very slow.
First step I am doing is creating a common UIView for every cell, essentially this is creating a white cell with a rounded effect on the cell with a shadow. The performance for this seems to be normal so I don't think it's the culprit.
Here is the code I am using to do this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NewsCellIdentifer = #"NewsCellIdentifier";
NewsItem *item = [self.newsArray objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NewsCellIdentifer];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NewsCellIdentifer];
cell.contentView.backgroundColor = [UIColor clearColor];
UIView *whiteRoundedCornerView = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,100)];
whiteRoundedCornerView.backgroundColor = [UIColor whiteColor];
whiteRoundedCornerView.layer.masksToBounds = NO;
whiteRoundedCornerView.layer.cornerRadius = 3.0;
whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(-1, 1);
whiteRoundedCornerView.layer.shadowOpacity = 0.5;
[cell.contentView addSubview:whiteRoundedCornerView];
[cell.contentView sendSubviewToBack:whiteRoundedCornerView];
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
cell.layer.opaque = YES;
cell.opaque = YES;
}
[cell.contentView addSubview:[self NewsItemThumbnailView:item]];
return cell;
}
Here is the method that returns the thumbnail view of the graphic and text:
- (UIView *) NewsItemThumbnailView:(NewsItem *)item
{
UIView *thumbNailMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 70)];
UIImageView *thumbNail = [[UIImageView alloc] initWithImage:[UIImage imageNamed:item.ThumbNailFileName]];
thumbNail.frame = CGRectMake(10,10, 45, 45);
UILabel *date = [[UILabel alloc] init];
date.frame = CGRectMake(10, 53, 45, 12);
date.text = item.ShortDateString;
date.textAlignment = NSTextAlignmentCenter;
date.textColor = [BVColors WebDarkGrey];
CGFloat fontSize = 10.0;
date.font = [BVFont Museo:&fontSize];
date.opaque = YES;
thumbNail.opaque = YES;
thumbNailMainView.opaque = YES;
[thumbNailMainView addSubview:thumbNail];
[thumbNailMainView addSubview:date];
return thumbNailMainView;
}
The performance problem seems to be when I add the thumbnail view to the cell because when I comment that line out, I don't seem to have it. The thumbnail information is dynamic and will change with each cell. I would appreciate any advice on how I should do this without degrading the performance.
UITableView will call tableView:cellForRowAtIndexPath: each time a cell comes into view, and dequeueReusableCellWithIdentifier: will reuse existing cell objects if they are available. These two facts combine to put you in a scenario where every time you scroll, the same finite number of cell objects end up with an increasing number of subviews.
The proper approach is to create a custom UITableViewCell subclass that has a property for thumbnailView. In the setter for that property, remove the previous thumbnail (if any) and then add the new one to the contentView. This ensures that you'll only ever have one thumbnail subview at any time.
A less optimal approach would be adding a tag to the UIView returned from NewsItemThumbnailView (thumbNailMainView.tag = someIntegerConstant) and then searching for any view with that tag and removing it before adding another:
// remove old view
UIView *oldThumbnailView = [cell.contentView viewWithTag:someIntegerConstant];
[oldThumbnailView removeFromSuperview];
// add new view
[cell.contentView addSubview:[self NewsItemThumbnailView:item]];
I ended up leveraging a solution found on this stackoverflow post:
How should I addSubview to cell.contentView?
Essentially when the cell is first initialized I am setting the view as mentioned by Nishant; however once the cell is reused I am extracting out the items I need to change, such as an UIImageView and then a UILabel. Since these are pointers I can modify just what I need when I need to and the performance is fast again. Here is a abbreviated version of what I did.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NewsCellIdentifer = #"NewsCellIdentifier";
NewsItem *item = [self.newsArray objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NewsCellIdentifer];
UIView *thumbNailMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 50, 70)];
UIImageView *thumbNail;
UIView *textMainView = [[UIView alloc] initWithFrame:CGRectMake(20,20,80,80)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(52,-5, 70, 20)];
UILabel *teaserLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,20, 210, 40)];
UIView *newsItemCornerMainView = [[UIView alloc] initWithFrame:CGRectMake(255.7, 55.2, 55, 55)];
UIImageView *cornerIconView;
// If the cell doesn't existing go ahead and make it fresh.
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:NewsCellIdentifer];
// Configure all the various subviews
..... //Sample below
// Make the title view
headerLabel.text = item.Title;
CGFloat textfontSize = 16.0f;
headerLabel.font = [BVFont Museo:&textfontSize];
headerLabel.textColor = [BVColors WebBlue];
headerLabel.textAlignment = NSTextAlignmentLeft;
headerLabel.numberOfLines = 0;
headerLabel.tag = 50;
// Make the Teaser view
teaserLabel.text = item.Teaser;
teaserLabel.numberOfLines = 0;
CGFloat tfontSize = 13.0f;
teaserLabel.textAlignment = NSTextAlignmentLeft;
teaserLabel.textColor = [BVColors WebDarkGrey];
teaserLabel.font = [BVFont HelveticaNeue:&tfontSize];
[teaserLabel sizeToFit];
teaserLabel.tag = 51;
[textMainView addSubview:headerLabel];
[textMainView sendSubviewToBack:headerLabel];
[textMainView addSubview:teaserLabel];
[cell.contentView addSubview:textMainView];
....
}
thumbNail = (UIImageView *) [cell viewWithTag:47];
[thumbNail setImage:[UIImage imageNamed:item.ThumbNailFileName]];
headerLabel = (UILabel *) [cell viewWithTag:50];
headerLabel.text = item.Title;
teaserLabel = (UILabel *) [cell viewWithTag:51];
teaserLabel.text = item.Teaser;
cornerIconView = (UIImageView *) [cell viewWithTag:48];
[cornerIconView setImage:[UIImage imageNamed:item.CornerIconFileName]];
return cell;
}
You should change thumbNailMainView content only everytime but you should not add its content on cell everytime.
So add this line where you are allocating cell
[cell.contentView addSubview:[self NewsItemThumbnailView:item]];
add this inside braces. and then access thumbNailMainView from cell and pass that item data which you need to change for each cell.
Assign a tag to thumbNailMainView and its subview thumbNail then access it as
UIView *_thumbNailMainView = [cell.contentView viewWithTag:_thumbNailMainView_tag];
UIImageView *_thumbNail = [_thumbNailMainView viewWithTag:thumbNail_tag];
_thumbNail.image = [UIImage imageNamed:item.ThumbNailFileName];
Hope it helps you.

can't change UITableViewCell background color

I have UITableViewCell that fits on UITableView, but somehow I can't change the background color when entering editing style mode.. I've tried everything on the web, search all day long, but still couldn't get it fixed (I've searched StackOverflow as-well). please, help me.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MainTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"MainTableViewCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (MainTableViewCell *)view;
}
}
}
Try customizing the cell inside tableView: willDisplayCell: method, something like this:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.backgroundColor = [UIColor redColor];
}
You need to change the tableView cell's contentView, not the cell's background view.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.contentView.backgroundColor = [UIColor redColor];
}
to have total control on the customisation of your cells, I prefer better to override the cell view,
create a new class for your cell view, that gets called by the UITableView,
later when i get to my work computer if you havent found your answer I will post some sample code,
once you see how it works is pretty easy
you could as well place an image for your cell background, and place different labels and images, buttons, textfields in custom places of your cell,
EDIT>>
the code! [is overkill just to change the background, but if you want to really customise your cell, this is the way to go!]
in your CustomCell.h
#import <UIKit/UIKit.h>
#interface CustomCell : UITableViewCell {
UILabel *_kLabel;
UILabel *_dLabel;
}
#property (nonatomic, retain) UILabel *kLabel;
#property (nonatomic, retain) UILabel *dLabel;
- (void) initLabels;
#end
in your CustomCell.m
#import "CustomCell.h"
#implementation CustomCell
#synthesize kLabel = _kLabel;
#synthesize dLabel = _dLabel;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
CGRect popUpImageBgndRect = CGRectMake(0, 0, 942, 44);
UIImageView *popUpImageBgnd = [[UIImageView alloc] initWithFrame:popUpImageBgndRect];
[popUpImageBgnd setImage:[UIImage imageNamed:#"tableCellBgnd.png"]];
popUpImageBgnd.opaque = YES; // explicitly opaque for performance
[self.contentView addSubview:popUpImageBgnd];
[popUpImageBgnd release];
[self initLabels];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGRect contentRect = self.contentView.bounds;
CGFloat boundsX = contentRect.origin.x;
CGRect frame;
frame= CGRectMake(boundsX+10 ,10, 200, 20);
self.kLabel.frame = frame;
frame= CGRectMake(boundsX+98 ,10, 100, 20);
self.dLabel.frame = frame;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void) initLabels {
self.kLabel = [[[UILabel alloc]init] autorelease];
self.kLabel.textAlignment = UITextAlignmentLeft;
self.kLabel.backgroundColor = [UIColor clearColor];
self.kLabel.font = [UIFont fontWithName:#"FS Albert" size:16];
self.kLabel.textColor = [UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1];
self.dLabel = [[[UILabel alloc]init] autorelease];
self.dLabel.textAlignment = UITextAlignmentLeft;
self.dLabel.backgroundColor = [UIColor clearColor];
self.dLabel.font = [UIFont systemFontOfSize:16];
self.dLabel.textColor = [UIColor colorWithRed:51.0f/255.0f green:51.0f/255.0f blue:51.0f/255.0f alpha:1];
[self.contentView addSubview:self.kLabel];
[self.contentView addSubview:self.dLabel];
}
-(void) dealloc {
[_kLabel release];
[_dLabel release];
[super dealloc];
}
#end
And in your ViewController.m
YourViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
return cell;
}
ENJOY!!
;)
try setting the cells backgroundColor property, worked for me cell.backgroundColor=[UIColor blueColor];
Please try this, it works for me.
UIView *bgView = [[UIView alloc] initWithFrame:cell.frame];
bgView.backgroundColor = [UIColor greenColor];
cell.backgroundView = bgView;
[bgView release];
As #Westley mentioned;
You need to change the tableView cell's contentView, not the cell's background view.
This is how you should do it:
if(index == conditionYouWant)
{
cell.contentView.backgroundColor = [UIColor whiteColor];
}
else
{
cell.contentView.backgroundColor = [UIColor colorWithRed:0.925 green:0.933 blue:0.937 alpha:1.0];
}
Hope it helps you guys out
Be sure you didn't already set the content view's background color in the Storyboard. If you did, changing the cell.backgroundColor in code will make no difference, and you will go round and round in confusion (like I did).
cell.backgroundColor = [UIColor redColor];
in swift 3 you can use
cell.backgroundcolor = UIColor.white

How to change text color for Section Headers in a Grouped TableView in iPhone SDK?

I am making an iPhone app where in I have a grouped TableView with headers for the sections.
Problem is that I want to change the Section Header's text color.
How can I change the text color of Section Header?
What should I do?
Add the following code to your AppDelegate class in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
method:
[[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setTextColor:[UIColor whiteColor]];
If you don't want to do it app wide like in Vahan's solution, here is a solution using one of UITableViewDelegate's method :
func tableView(tableView: UITableView, willDisplayHeaderView view:UIView, forSection: Int) {
if let headerView = view as? UITableViewHeaderFooterView {
headerView.textLabel?.textColor = UIColor.redColor()
}
}
This is SURELY gonna work for you.
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *tempView=[[UIView alloc]initWithFrame:CGRectMake(0,200,300,244)];
tempView.backgroundColor=[UIColor clearColor];
UILabel *tempLabel=[[UILabel alloc]initWithFrame:CGRectMake(15,0,300,44)];
tempLabel.backgroundColor=[UIColor clearColor];
tempLabel.shadowColor = [UIColor blackColor];
tempLabel.shadowOffset = CGSizeMake(0,2);
tempLabel.textColor = [UIColor redColor]; //here you can change the text color of header.
tempLabel.font = [UIFont fontWithName:#"Helvetica" size:fontSizeForHeaders];
tempLabel.font = [UIFont boldSystemFontOfSize:fontSizeForHeaders];
tempLabel.text=#"Header Text";
[tempView addSubview:tempLabel];
[tempLabel release];
return tempView;
}
just copy and paste this function in your code.
You can implement this table view data source method:
- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section
{
//create your custom label here & anything else you may want to add
return YourCustomView;
}
I built off of the answer from #Harsh.
This is the closest I could get, indistinguishable from what I can tell.
It goes in the <UITableViewDataSource> obviously.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *hView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
hView.backgroundColor=[UIColor clearColor];
UILabel *hLabel=[[[UILabel alloc] initWithFrame:CGRectMake(19,17,301,21)] autorelease];
hLabel.backgroundColor=[UIColor clearColor];
hLabel.shadowColor = [UIColor whiteColor];
hLabel.shadowOffset = CGSizeMake(0.5,1); // closest as far as I could tell
hLabel.textColor = [UIColor blackColor]; // or whatever you want
hLabel.font = [UIFont boldSystemFontOfSize:17];
hLabel.text = #"Your title here"; // probably from array
[hView addSubview:hLabel];
return hView;
}
#Harsh 's answer worked great for me, and by changing the coordinations of UILabel you can move it around. Also, I, personally thought to change the shadow offset a bit to make it more readable, but that could be a personal choice. Here's my version in case:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
if (sectionTitle == nil) {
return nil;
}
// Create label with section title
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(40, -5, 300, 30)] autorelease];
//If you add a bit to x and decrease y, it will be more in line with the tableView cell (that is in iPad and landscape)
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor yellowColor];
label.shadowColor = [UIColor whiteColor];
label.shadowOffset = CGSizeMake(0.5., 0.5.);
label.font = [UIFont boldSystemFontOfSize:18];
label.text = sectionTitle;
// Create header view and add label as a subview
UIView *view = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, SectionHeaderHeight)]autorelease];
[view addSubview:label];
return view;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UILabel *myLabel = [[UILabel alloc] init];
myLabel.frame = CGRectMake(20, 8, 220, 20);
myLabel.font = [UIFont boldSystemFontOfSize:16];
myLabel.text = [self tableView:tableView
titleForHeaderInSection:section];
myLabel.backgroundColor=[UIColor grayColor];
UIView *headerView = [[UIView alloc] init];
[headerView addSubview:myLabel];
return headerView;
}

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.

How to reliably subclass UITableViewCell for grouped UITableView?

When writing a customized subclass of UITableViewCell, I find that the results work well for the rectangular cells of a plain-styled UITableView, but do not work at all for the rounded cells in a grouped-styled table.
Is there a way to reliably subclass UITableViewCell to draw cells which work for grouped-style tables? (Without using Interface Builder.)
Could the answer be as simple as first calling [super layoutSubviews] inside your UITableViewCell subclass’s layoutSubviews method?
Here is my code.
First I create the UITextField and add it to the contentView in the initWithStyle: method:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
inputField = [[UITextField alloc] initWithFrame:CGRectZero];
[self.contentView addSubview:inputField];
inputField.borderStyle = UITextBorderStyleLine;
[inputField release];
}
return self;
}
Then in layoutSubviews, I’ve got this:
-(void)layoutSubviews
{
inputField.frame = CGRectMake(5, 5, 100, 20);
}
With that code, the text field is 5px from the left of the screen, which is, of course, 5px to the left of the table cell when it’s in grouped mode. In other words, OUTSIDE of the table view cell. No good.
Use this code and the inputField is placed 5px to the right of the cell, like I want it to be:
-(void)layoutSubviews
{
[super layoutSubviews]; // the magic line
inputField.frame = CGRectMake(5, 5, 100, 20);
}
I could have totally misunderstood the problem you were having, though!
Erik
I used to have lots of problems with UITableViewCell subclasses, but then I just stopped subclassing.
Adding subviews to the contentView property of a UITableViewCell seems to accomplish the same thing in any instance that I've run across, so I just do that inside my UITableViewController.
Here's an example that has a title and value:
- (UITableViewCell *)tableView:(UITableView*)tableView
cellForRowAtIndexPath: (NSIndexPath*)indexPath
{
static NSString* CellIdentifier = #"AccountDetailsCell";
UILabel* mainLabel = nil;
UILabel* valueLabel = nil;
const CGFloat kAccountDetailFontSize = 14.0;
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
if ( cell == nil )
{
cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault
reuseIdentifier: CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake( 10.0, 0.0, 150.0, 44.0 )] autorelease];
mainLabel.tag = MAINLABEL_TAG;
mainLabel.font = [UIFont boldSystemFontOfSize: kAccountDetailFontSize];
mainLabel.textAlignment = UITextAlignmentLeft;
mainLabel.textColor = [UIColor darkGrayColor];
mainLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight;
mainLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: mainLabel];
valueLabel = [[[UILabel alloc] initWithFrame: CGRectMake( 150.0, 0.0, 150.0, 44.0 )] autorelease];
valueLabel.tag = VALUELABEL_TAG;
valueLabel.font = [UIFont boldSystemFontOfSize: kAccountDetailFontSize];
valueLabel.textAlignment = UITextAlignmentRight;
valueLabel.textColor = [UIColor darkTextColor];
valueLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
valueLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview: valueLabel];
}
else
{
mainLabel = (UILabel*)[cell.contentView viewWithTag: MAINLABEL_TAG];
valueLabel = (UILabel*)[cell.contentView viewWithTag: VALUELABEL_TAG];
}
mainLabel.text = (NSString*)kCellTitles[indexPath.section][indexPath.row];
valueLabel.text = [self tableView: tableView valueLabelTextForRowAtIndexPath: indexPath];
return cell;
}
I've noticed this problem as well. My workaround has been to just make my table cells smaller (300 width instead of 320). It's not a great solution, but it works well.
I don't believe you can get rid of the table view insets on an individual basis when in "grouped" mode. I could be wrong though!
What problem are you having? In drawRect you are given a rect, and know your total size - just conform to that space. If you are using layoutSubviews, same thing.