Ось мій робочий фрагмент коду:
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)
Я додав 4px до розрахункової висоти, тому що без цих 4px не вистачає одного рядка.
Я використовую цей фрагмент коду в tableView і додаю "висоту" до масиву NSNumbers, і я отримую правильну висоту комірки за замовчуванням textLabel.
Додайте ще 4 пікселі, якщо потрібно більше місця під текстом у ярлику textLabel.
**** ОНОВИТИ ****
Я не погоджуюсь з "помилкою ширини 40 пікселів", я кричу, що це 4 пікселі відсутньої висоти, оскільки 4 пікселі - це висота за замовчуванням пробілу між літерою та межею одного рядка. Ви можете перевірити це за допомогою UILabel, для розміру шрифту 16 потрібна висота UILabel 20.
Але якщо у вашому останньому рядку немає "g" або що-небудь інше, вимірювання може бути відсутнє у 4px висоти.
Я перевірив це невеликим методом, я отримую точну висоту 20,40 або 60 для моєї наклейки та правильну ширину менше 300px.
Для підтримки 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, я додав код діагностики-pragma, щоб видалити попередження для цього конкретного виклику функції / блоку коду.
- (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 простір рядків для кожного рядка, вам потрібно отримати результат висоти.
Будь ласка, майте це на увазі під час кодування!
У мене ще немає функції для цієї "проблеми", але я оновлю цю публікацію, коли закінчу.