My application uses abbreviations in UITableView
section header titles that are hard for VoiceOver to pronounce. As I need to make these titles pronounceable by
If anyone is still interested, I've got it looking pretty damn close with the following code (using Mark Adams images from the comment above, but I resized them slightly as my app also has landscape mode):
- (UIView *)tableView:(UITableView *)tbl viewForHeaderInSection:(NSInteger)section
{
UIView* sectionHead = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tbl.bounds.size.width, 18)];
sectionHead.backgroundColor = [UIColor colorWithWhite:0 alpha:0];
sectionHead.userInteractionEnabled = YES;
sectionHead.tag = section;
UIImageView *headerImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"PlainTableViewSectionHeader.png"]];
headerImage.contentMode = UIViewContentModeScaleAspectFit;
[sectionHead addSubview:headerImage];
[headerImage release];
UILabel *sectionText = [[UILabel alloc] initWithFrame:CGRectMake(10, 2, tbl.bounds.size.width - 10, 18)];
sectionText.text = text;
sectionText.backgroundColor = [UIColor clearColor];
sectionText.textColor = [UIColor whiteColor];
sectionText.shadowColor = [UIColor darkGrayColor];
sectionText.shadowOffset = CGSizeMake(0,1);
sectionText.font = [UIFont boldSystemFontOfSize:18];
[sectionHead addSubview:sectionText];
[sectionText release];
return [sectionHead autorelease];
}
I would create a custom UIView class and add a UILabel to it for the section heading text. For the background, use a UIImageView and load the appropriate image for the background of the section header. Assign this UIImageView with the addSubView: method for your UIView.
In the UITableViewController you can set tableView.sectionHeaderHeight to customise the height of all section headers. Using the UITableViewDelegate method:
tableView:viewForHeaderInSection:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITableViewDelegate
You should return an instance of your custom UIView with the text label as the heading for the section.
You should add a shadow to the UILabel and adjust all colours to suit the default style. Since section headers are also slightly transparent, you can set your UIView alpha with
self.alpha = 0.9f;
Here's an implementation of a UILabel subclass which mimics the background programatically:
UITableViewStandardHeaderLabel.h
#import <UIKit/UIKit.h>
@interface UITableViewStandardHeaderLabel : UILabel
@property (nonatomic) CGFloat topInset;
@property (nonatomic) CGFloat leftInset;
@property (nonatomic) CGFloat bottomInset;
@property (nonatomic) CGFloat rightInset;
@end
UITableViewStandardHeaderLabel.m:
/*!
* @class UITableViewStandardHeaderLabel
* @brief Reimplementation of the UILabel used for a standard UITableView's group headers for customization purposes
*/
@implementation UITableViewStandardHeaderLabel
@synthesize topInset, leftInset, bottomInset, rightInset;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)drawTextInRect:(CGRect)rect
{
UIEdgeInsets insets = {self.topInset, self.leftInset, self.bottomInset, self.rightInset};
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGGradientRef backgroundGradient;
CGColorSpaceRef rgbColorspace;
size_t num_locations = 2;
CGFloat locations[2] = { 0.0f, 1.0f };
CGFloat components[8] = { 144.0f/255.0f, 159.0f/255.0f, 171.0f/255.0f, 1.0f,
/* start */ 183.0f/255.0f, 192.0f/255.0f, 200.0f/255.0f, 1.0f /* end */ };
rgbColorspace = CGColorSpaceCreateDeviceRGB();
backgroundGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, num_locations);
CGRect currentBounds = self.bounds;
CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMinY(currentBounds));
CGPoint bottomCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));
CGContextDrawLinearGradient(context, backgroundGradient, topCenter, bottomCenter, 0);
UIColor *topBorderLineColor = [UIColor colorWithRed:113.0f/255.0f green:125.0f/255.0f blue:133.0f/255.0f alpha:1.0];
UIColor *secondLineColor = [UIColor colorWithRed:165.0f/255.0f green:177.0f/255.0f blue:187.0f/255.0f alpha:1.0];
UIColor *bottomBorderLineColor = [UIColor colorWithRed:151.0f/255.0f green:157.0f/255.0f blue:164.0f/255.0f alpha:1.0];
[topBorderLineColor setFill];
CGContextFillRect(context, CGRectMake(0, 0, CGRectGetMaxX(currentBounds), 1));
[bottomBorderLineColor setFill];
CGContextFillRect(context, CGRectMake(0, CGRectGetMaxY(currentBounds)-1, CGRectGetMaxX(currentBounds), 1));
[secondLineColor setFill];
CGContextFillRect(context, CGRectMake(0, 1, CGRectGetMaxX(currentBounds), 1));
[super drawRect:rect];
}
@end
I found that the other answers either don't work or don't mimic the standard look. Here's mine, which works for iOS 5 and 6.
Note that if you're on iOS 6, you should use dequeueReusableHeaderFooterViewWithIdentifier
, which makes things much easier and cleaner.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if ([tableView respondsToSelector:@selector(dequeueReusableHeaderFooterViewWithIdentifier:)])
{
static NSString *headerReuseIdentifier = @"TableViewSectionHeaderViewIdentifier";
UITableViewHeaderFooterView *sectionHeaderView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier];
if(sectionHeaderView == nil){
sectionHeaderView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:headerReuseIdentifier];
}
//customise the label here:
//[sectionHeaderView.textLabel setTextColor:[UIColor whiteColor]];
return sectionHeaderView;
}
else
{
UIView* headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44.0)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(20.0, 10, 290, 0)];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.text = [self tableView:tableView titleForHeaderInSection:section];
headerLabel.font = [UIFont boldSystemFontOfSize:17];
headerLabel.textAlignment = NSTextAlignmentLeft;
headerLabel.shadowColor = [UIColor clearColor];
headerLabel.numberOfLines = 0;
[headerLabel sizeToFit];
[headerView setFrame:CGRectMake(headerView.frame.origin.x, headerView.frame.origin.y, headerView.frame.size.width, headerLabel.bounds.size.height)];
//some customisation:
headerLabel.textColor = [UIColor whiteColor];
[headerView addSubview: headerLabel];
return headerView;
}
}
As the docs say, if you implement viewForHeaderInSection
you must also implement heightForHeaderInSection
. Implement it like this to make sure that it gets the right size for any number of lines:
-(float)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return UITableViewAutomaticDimension;
}