问题
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 VoiceOver, I need to give the section header title a accessibilityLabel.
It seems that the only way to do this is to draw a custom section header cell. I would like to mimic the standard Apple UIKit provided style for these custom section headers but I am uncertain on how to emulate Apple's detailed look of this element.
What is the best approach to mimic the UITableViewStylePlain section header style?
Update: I am well aware how to create a custom header cell. What I am looking for is a technique to mimic exactly the look of the header cell style as provided by Apple for the plain UITableView section header cells.
回答1:
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];
}
回答2:
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
回答3:
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;
}
回答4:
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;
来源:https://stackoverflow.com/questions/4664687/how-to-mimic-uitableviews-uitableviewstyleplain-section-header-style