Вот мой рабочий фрагмент кода:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];
NSString *headline = [dict objectForKey:@"title"];
UIFont *font = [UIFont boldSystemFontOfSize:18];
CGRect rect = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
CGFloat height = roundf(rect.size.height +4)
Я добавил 4 пикселя к расчетной высоте, потому что без этих 4 пикселей не хватает одной строки.
Я использую этот фрагмент кода в tableView и добавляю «высоту» к массиву NSNumbers, и я получаю правильную высоту ячейки для textLabel по умолчанию.
Добавьте еще 4 пикселя, если вам нужно больше места под текстом в textLabel.
**** ОБНОВИТЬ ****
Я не согласен с «ошибкой ширины 40 пикселей», я кричу, что это 4 пикселя отсутствующей высоты, потому что 4 пикселя - это высота по умолчанию для промежутка между буквой и границей одной строки. Вы можете проверить это с помощью UILabel, для размера шрифта 16 вам понадобится высота UILabel 20.
Но если в вашей последней строке нет буквы «g» или чего-то еще, измерение может не соответствовать высоте в 4 пикселя.
Я перепроверил это небольшим методом, я получил точную высоту 20,40 или 60 для моей метки и правильную ширину менее 300 пикселей.
Для поддержки iOS6 и iOS7 вы можете использовать мой метод:
- (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (iosVersion >= 7.0) {
rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
}
NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
return rect.size.height;
}
**** ОБНОВИТЬ ****
Благодаря вашим комментариям я обновил свою функцию следующим образом. Поскольку sizeWithFont устарел и вы получите предупреждение в XCode, я добавил диагностический-прагма-код, чтобы удалить предупреждение для этого конкретного вызова функции / блока кода.
- (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
#pragma GCC diagnostic pop
}
return ceil(rect.size.height);
}
В дополнение к теме 4px: в зависимости от того, какой шрифт и вес шрифта вы используете, расчет возвращает разные значения высоты. В моем случае: HelveticaNeue-Medium с размером шрифта 16,0 возвращает высоту строки 20,0 для одной строки, но 39,0 для двух строк, 78 пикселей для 4 строк -> 1 пиксель отсутствует для каждой строки - начиная со строки 2 - но вы хотите чтобы иметь размер шрифта + 4px для каждой строки, вы должны получить результат по высоте.
Помните об этом при написании кода!
У меня еще нет функции для этой "проблемы", но я обновлю этот пост, когда закончу.