Dev:UITableViewCellLayoutManager

From The Apple Wiki

UITableViewCellLayoutManager is a model class for styling a UITableViewCell. It is the class that powers the "style" in the -[UITableViewCell initWithStyle:reuseIdentifier:] method. UITableViewCellLayoutManager is available since 3.0.

You can set your own layout manager to a table view cell with its layoutManager property.

Everything that can be done with layout manager can also be done with a subclass of UITableViewCell, which is SDK-compliant.

Predefined layout managers

Signature +(UITableViewCellLayoutManager*)layoutManagerForTableViewCellStyle:(UITableViewCellStyle)cellStyle;
Available in 3.0 –

There are 6 predefined layout managers, 5 of which can be obtained using the +[UITableViewCellLayoutManager layoutManagerForTableViewCellStyle:] method:

Style Manager class
0 (UITableViewCellStyleDefault) UITableViewCellLayoutManager
1 (UITableViewCellStyleValue1) UITableViewCellLayoutManagerValue1
2 (UITableViewCellStyleValue2) UITableViewCellLayoutManagerValue2
3 (UITableViewCellStyleSubtitle) UITableViewCellLayoutManagerSubtitle
1000 UITableViewCellLayoutManagerEditable1
- UIMoreListCellLayoutManager

Subclassing layout managers

Result of the setting the layout manager defined on the left.

Subclassed layouts usually need to override -layoutSubviewsOfCell:, -textLabelForCell:, -detailTextLabelForCell:, --defaultTextLabelFontSizeForCell: and -defaultDetailTextLabelFontSizeForCell:. The following is an example layout manager:

@interface XXLayoutManager : UITableViewCellLayoutManager {}
@end
@implementation XXLayoutManager
-(UILabel*)detailTextLabelForCell:(UITableViewCell*)cell {
	UILabel* label = [self defaultLabelForCell:cell];
	label.textColor = [UIColor redColor];
	label.shadowColor = [UIColor colorWithWhite:0 alpha:0.5];
	label.shadowOffset = CGSizeMake(1, 1);
	return label;
}
-(CGFloat)defaultDetailTextLabelFontSizeForCell:(UITableViewCell*)cell { return [UIFont systemFontSize]; }
-(void)layoutSubviewsOfCell:(UITableViewCell*)cell {
	[super layoutSubviewsOfCell:cell];
	CGRect contentBounds = cell.contentView.bounds;
	
	UIImageView* imageView = [cell _imageView:NO];
	if (imageView != nil) {
		CGRect imageFrame = imageView.frame;
		CGFloat leftPadding = imageFrame.origin.x + imageFrame.size.width;
		contentBounds.origin.x += leftPadding;
		contentBounds.size.width -= leftPadding;
	}
	
	UILabel* textLabel = [cell _textLabel:NO];
	if (textLabel != nil) {
		CGFloat fontSize = textLabel.font.pointSize;
		if (fontSize == 0)
			textLabel.font = [UIFont boldSystemFontOfSize:[self defaultTextLabelFontSizeForCell:cell]];
		NSString* text = textLabel.text;
		if (text == nil || [text length] == 0)
			[textLabel removeFromSuperview];
		else if (textLabel.superview == nil)
			[cell.contentView addSubview:textLabel];
	}
	
	UILabel* detailTextLabel = [cell _detailTextLabel:NO];
	CGFloat detailWidth = 0;
	if (detailTextLabel != nil) {
		UIFont* font = detailTextLabel.font;
		CGFloat fontSize = font.pointSize;
		if (fontSize == 0)
			detailTextLabel.font = font = [UIFont boldSystemFontOfSize:[self defaultDetailTextLabelFontSizeForCell:cell]];
		NSString* text = detailTextLabel.text;
		if (text == nil || [text length] == 0)
			[detailTextLabel removeFromSuperview];
		else {
			detailWidth = [text sizeWithFont:font].width;
			if (detailTextLabel.superview == nil)
				[cell.contentView addSubview:detailTextLabel];
		}
	}
	
	cell.contentView.bounds = contentBounds;
	const CGFloat vpad = 5, hpad = 20;
	textLabel.frame = CGRectMake(hpad, vpad, contentBounds.size.width-detailWidth-3*hpad, contentBounds.size.height-2*vpad);
	detailTextLabel.frame = CGRectMake(contentBounds.size.width-detailWidth-hpad, vpad, detailWidth, contentBounds.size.height-2*vpad);
}
@end

References