Reputation: 487
So here how it goes: I'm implementing a UITableView (grouped style, with 1 section) with standard UITableViewCells (style - UITableViewCellStyleSubtitle) as content. My textLabel.text can be really long, that's why I set some params in TableView:cellForRowAtIndexPath:
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont boldSystemFontOfSize:CELL_FONT_SIZE];
cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.detailTextLabel.numberOfLines = 0;
[self configureCell:cell atIndexPath:indexPath];
To resize the cell height I've implemented tableView:heightForRowAtIndexPath: as follows:
Test *test = (Test *)[self.frc objectAtIndexPath:indexPath];
NSString *cellText = test.test_name;
UIFont *cellFont = [UIFont boldSystemFontOfSize:CELL_FONT_SIZE];
CGFloat horizontalConstraint;
if (self.bagdePresent)
{
// there will be big badge!
horizontalConstraint = 250.0f;
} else
{
// there will NO badge
horizontalConstraint = 280.0f;
}
CGSize constraintSize = CGSizeMake(horizontalConstraint, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
// return label height, 20 as gap, 30 for rating image,
return labelSize.height + 20 + 30;
First I check if there will be badge image in the cell, if so, I reduce horizontal space available.
And here's the problem (finally): for some strings (some string lengths) sizeWithFont:constrainedToSize:lineBreakMode: returns value that is less than real cell's textLabel height when I set its text property to the same string. As a result some if the cells have textLabels bigger than cell's bounds. When I add\remove some words to\from the string which displayed wrong, sizeWithFont:constrainedToSize:lineBreakMode: gives exact height which is later confirmes with textLabel actual height.
I thought it might be a problem with font, but as you see the font is the same. Where to dig from here? ;)
UPD1:
Here's an example of textLabel being taller than it was calculated in heightForRowAtIndexPath:
Upvotes: 2
Views: 1278
Reputation: 5519
I would recommend to take advantage of sizeToFit
. First you set the width of your label to your horizontalConstraint
, then you call [cell.textLabel sizeToFit]
(that will adjust the height of the label to fit it's content but leave the width as you set it (almost - that means it might become a little narrower):
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat horizontalConstraint;
if (self.bagdePresent)
{
// there will be big badge!
horizontalConstraint = 250.0f;
} else
{
// there will NO badge
horizontalConstraint = 280.0f;
}
Test *test = (Test *)[self.frc objectAtIndexPath:indexPath];
NSString *cellText = test.test_name;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = test.test_name;
UIFont *cellFont = [UIFont boldSystemFontOfSize:CELL_FONT_SIZE];
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;
label.font = cellFont;
CGRect frame = label.frame;
frame.size.width = horizontalConstraint;
label.frame = frame;
[label sizeToFit];
CGSize labelSize = label.frame.size;
// return label height, 20 as gap, 30 for rating image,
return labelSize.height + 20 + 30;
}
Upvotes: 2