Вычисление высоты многострочного текста для UILabel/UITableViewCell: разные результаты при вычислении и фактическом рисовании
Эта общая тема задавалась здесь несколько раз: как отображать UITableViewCells с различным количеством текста и, следовательно, с разной высотой. Канонический ответ: вы вычисляете высоту в делегате контроллера табличного представления в heightForRowAtIndexPath, используя sizeWithFont: constrainedToSize: lineBreakMode:. Позже ячейка нарисована, и при необходимости вы используете что-то вроде [label sizeToFit], и все работает как магия.
Моя проблема: я получаю обертку для некоторых ячеек, потому что sizeWithFont: возвращает разные размеры из фактического чертежа.
Конкретный пример:
Текст таков: "Люди забывают, что в 1993 году у @BillGates был сексуальный слот толщиной в 1/4 дюйма в 1993 году от NEC. Что бы ни случилось на этой неделе, НЕ будет об оборудовании!"
CGSize theSize = [text sizeWithFont:[UIFont systemFontOfSize:17.0f] constrainedToSize:CGSizeMake(310.0f, FLT_MAX) lineBreakMode:UILineBreakModeWordWrap];
NSLog(@"calculated size for %@: %f, %f",text, theSize.width, theSize.height);
Это возвращает: 306.000000, 84.000000. (I.e 4 строки с 17px шрифтом и 4px linespacing, 21px leading.) Хорошо.
Однако позже, когда на самом деле рисует ячейку:
label = (UILabel *)[cell viewWithTag:3];
label.text = [NSString stringWithFormat:@"%@", text];
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont systemFontOfSize:17.0f];
CGSize labelSize;
labelSize = label.frame.size;
NSLog(@"label size before resizing: %f, %f", labelSize.width, labelSize.height);
[label sizeToFit];
labelSize = label.frame.size;
NSLog(@"label size after resizing: %f, %f for text %@", labelSize.width, labelSize.height,text);
(UILabel загружается как часть UITableViewCell из NIB. В IB я устанавливаю его шириной 310 пикселей).
Это должно возвращать точно такой же размер, как указано выше. Вместо этого я получаю 281.000000, 105.000000 в качестве размеров после вызова sizeToFit. Это теперь 5 строк при времени рисования вместо 4, и текст просыпается, я вижу переполнение в пользовательском интерфейсе.
Итак, для того же текста я получаю два разных измерения, рассчитанных и не могу понять. Это что-то о UILabel? Имеет ли он некоторые внутренние поля? Это продолжается для некоторых текстов, но не для других, и я не прослеживал его в чем-то особенном о струнах; кажется случайным. В этом разделе подчеркивается, что есть два прохода обработки: вычисление высоты и фактического чертежа. Это согласуется с тем, что я вижу. Но я не понимаю, что именно происходит или как это исправить.
Вопрос: почему я вижу два разных расчетных размера и как их исправить?
Ответы
Ответ 1
Конечно, решение очевидно 30 секунд после публикации. Может быть, полезно и другим...
Размер sizeWithFont:
был правильным. Размеры, которые я вычислял выше, были неправильными, потому что [label sizeToFit]
уменьшает ширину рамки метки. При последующих вызовах одного и того же кода он начинался с кадра, который уже может быть уменьшен.
Исправление состояло в простом reset кадре width
до известной хорошей ширины до того, как размер будет соответствовать:
CGRect labelFrame = label.frame;
labelFrame.size.width = 310;
label.frame = labelFrame;
[label sizeToFit];
Ответ 2
Для многострочных меток вам нужно установить
cell.textLabel.numberOfLines = 0;
а затем
[cell.textLabel sizeToFit];
Но для приятного просмотра вам нужно добавить некоторые пиксели заполнения. И ваше приложение будет потрясающим!
Ответ 3
titleSize = [title sizeWithFont:[UIFont systemFontOfSize:(CGFloat)17.0]
constrainedToSize:CGSizeMake(280, 2000)
lineBreakMode:NSLineBreakByWordWrapping];