Подтвердить что ты не робот

Вычисление высоты многострочного текста для 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? Имеет ли он некоторые внутренние поля? Это продолжается для некоторых текстов, но не для других, и я не прослеживал его в чем-то особенном о струнах; кажется случайным. В этом разделе подчеркивается, что есть два прохода обработки: вычисление высоты и фактического чертежа. Это согласуется с тем, что я вижу. Но я не понимаю, что именно происходит или как это исправить.

Вопрос: почему я вижу два разных расчетных размера и как их исправить?

4b9b3361

Ответ 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];