I used the following function in some of my projects, but recently I created a small example that assumes that it is not reliable (at least in some situations):
[NSString sizeWithFont:font constrainedToSize:size]
[NSString sizeWithFont:font constrainedToSize:size lineBreakMode:lineBreak]
I created a custom UITableViewCell class to achieve results, as seen from the iPhone Photo Album app, for example. Image with album name and number of pictures in album. I used the above function to configure my long text (for counting). Here is the code:
Interface File:
#import <UIKit/UIKit.h>
@interface CustomValue2Cell : UITableViewCell {
UIImageView *cellImage;
UILabel *cellTextLabel;
UILabel *cellDetailTextLabel;
}
@property (nonatomic, retain) UIImageView *cellImage;
@property (nonatomic, retain) UILabel *cellTextLabel;
@property (nonatomic, retain) UILabel *cellDetailTextLabel;
- (void)setCellImage:(UIImage *)image withText:(NSString *)text andDetail:(NSString *)detail;
- (CGSize)getSizeOfText:(NSString *)text withFont:(UIFont *)font;
@end
Implementation File:
#import "CustomValue2Cell.h"
@implementation CustomValue2Cell
@synthesize cellImage;
@synthesize cellTextLabel;
@synthesize cellDetailTextLabel;
# define kImageXPosition 3
# define kImageYPosition 3
# define kImageWidth 37.0
# define kImageHeight 37.0
# define kTextXPosition 55
# define kTextYPosition 10
# define kTextWidth 200
# define kTextHeight 22
# define kDetailXPosition 55
# define kDetailYPosition 10
# define kDetailWidth 40
# define kDetailHeight 22
# define kCellSubviewDisplacement 20
# define kTextLabelFontSize 18
# define kDetailLabelFontSize 16
- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {
UIColor *textLabelColor = [UIColor blackColor];
UIFont *textLabelFont = [UIFont systemFontOfSize:kTextLabelFontSize];
UIColor *detailTextColor = [UIColor darkGrayColor];
UIFont *detailTextFont = [UIFont systemFontOfSize:kDetailLabelFontSize];
UIColor *highlightedTextColor = [UIColor whiteColor];
CGRect rect;
rect = CGRectMake(kImageXPosition, kImageYPosition, kImageWidth, kImageHeight);
cellImage = [[UIImageView alloc] initWithFrame:rect];
rect = CGRectMake(kTextXPosition, kTextYPosition, kTextWidth, kTextHeight);
cellTextLabel = [[UILabel alloc] initWithFrame:rect];
[cellTextLabel setFont:textLabelFont];
[cellTextLabel setTextColor:textLabelColor];
[cellTextLabel setHighlightedTextColor:highlightedTextColor];
rect = CGRectMake(kDetailXPosition, kDetailYPosition, kDetailWidth, kDetailHeight);
cellDetailTextLabel = [[UILabel alloc] initWithFrame:rect];
[cellDetailTextLabel setFont:detailTextFont];
[cellDetailTextLabel setTextColor:detailTextColor];
[cellDetailTextLabel setHighlightedTextColor:highlightedTextColor];
[[self contentView] addSubview:cellImage];
[[self contentView] addSubview:cellTextLabel];
[[self contentView] addSubview:cellDetailTextLabel];
self.selectionStyle = UITableViewCellSelectionStyleBlue;
}
return self;
}
- (void)setCellImage:(UIImage *)image withText:(NSString *)text andDetail:(NSString *)detail {
cellImage.image = image;
cellTextLabel.text = text;
cellDetailTextLabel.text = detail;
UIFont *textLabelFont = [UIFont systemFontOfSize:kTextLabelFontSize];
CGSize size = [self getSizeOfText:text withFont:textLabelFont];
CGRect frame = CGRectMake(kDetailXPosition, kDetailYPosition, kDetailWidth, kDetailHeight);
frame.origin.x = frame.origin.x + size.width + kCellSubviewDisplacement;
[cellDetailTextLabel setFrame:frame];
}
- (CGSize)getSizeOfText:(NSString *)text withFont:(UIFont *)font {
return [text sizeWithFont:font constrainedToSize:CGSizeMake(kTextWidth, kTextHeight)];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
}
- (void)dealloc {
[cellImage release];
[cellTextLabel release];
[cellDetailTextLabel release];
[super dealloc];
}
@end
To test my custom class, I prepared a list of fonts and displayed them in my View table. Code for getting a list of available fonts:
fontFamily = [[NSMutableArray alloc] initWithArray:[UIFont familyNames]];
fonts = [[NSMutableArray alloc] init];
for(NSUInteger i=0; i<[fontFamily count]; i++) {
NSString *familyName = [fontFamily objectAtIndex:i];
NSArray *array = [UIFont fontNamesForFamilyName:familyName];
[fonts addObjectsFromArray:array];
}
Here is the code to return the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
CGRect rect = CGRectMake(0.0, 0.0, 320.0, 50.0);
CustomValue2Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomValue2Cell alloc] initWithFrame:rect reuseIdentifier:CellIdentifier] autorelease];
}
NSString *font = [fonts objectAtIndex:indexPath.row];
NSString *detail = [NSString stringWithFormat:@"%d", [[fonts objectAtIndex:indexPath.row] length]];
[cell setCellImage:[UIImage imageNamed:@"Pointy.gif"] withText:font andDetail:detail];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]
return cell;
}
Result: Text Label and Detail Text Label are overlapping for some values. e.g. "CouierNewPS-BoldMT" and "25" overlap each other, and in some other cases, they are not overlapping but they are very close.
Question: Is their a better alternative to -sizeWithFont function? Or, am i doing something very stupid to mess things up?
. . .