Расчет высоты многострочного текста для UILabel / UITableViewCell: разные результаты при расчете по сравнению с фактическим рисунком - PullRequest
39 голосов
/ 26 января 2010

Эта общая тема задавалась здесь несколько раз: как визуализировать UITableViewCells с различным количеством текста и, следовательно, с различной высотой. Канонический ответ: вы вычисляете высоту в делегате контроллера табличного представления в heightForRowAtIndexPath, используя sizeWithFont: constrainedToSize: lineBreakMode :. Позже ячейка рисуется, и вы используете что-то вроде [label sizeToFit], если необходимо, и все работает как по волшебству.

Моя проблема: я получаю обтекание для некоторых ячеек, потому что sizeWithFont: возвращает размеры, отличные от реального чертежа.

Конкретный пример:

Текст таков: «Люди забывают, что у @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. (Т.е. 4 строки с шрифтом 17px и межстрочным интервалом 4px, 21px в начале.) Хорошо.

Однако позже при рисовании ячейки:

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 я установил его шириной 310px.)

Это должно вернуть точно такой же размер, как указано выше. Вместо этого я получаю 281.000000, 105.000000 как размеры после вызова sizeToFit. Сейчас во время рисования 5 линий вместо 4, и текст перетекает, я вижу побочный эффект в пользовательском интерфейсе.

Итак, для одного и того же текста я вычисляю два разных измерения и не могу понять это. Это что-то про UILabel? Есть ли у него какие-то внутренние поля? Это продолжается для некоторых текстов, но не для других, и я не проследил это до чего-то особенного в строках; кажется случайным. В этой теме подчеркивается, что существует два этапа обработки: вычисление высоты по сравнению с фактическим чертежом. Это соответствует тому, что я вижу. Но я не понимаю, что именно происходит и как это исправить.

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

Ответы [ 3 ]

36 голосов
/ 26 января 2010

Конечно, решение очевидно 30 секунд после публикации. Может быть, полезно и для других ...

Размер по sizeWithFont: был верным. Размеры, которые я рассчитал вышеописанным способом, были неверными, потому что [label sizeToFit] уменьшает ширину рамки метки. При последующих вызовах того же кода он начинался с кадра, который, возможно, уже был уменьшен.

Исправление состояло в том, чтобы просто сбросить рамку width на известную хорошую ширину, прежде чем выбрать размер:

CGRect labelFrame = label.frame;
labelFrame.size.width = 310;
label.frame = labelFrame;
[label sizeToFit];
11 голосов
/ 10 августа 2011

Для многострочных меток вам нужно установить

cell.textLabel.numberOfLines = 0;

, а затем

[cell.textLabel sizeToFit];

Но для красивого вида вам нужно добавить несколько отступных пикселей. И ваше приложение будет потрясающим!

6 голосов
/ 12 июня 2013
 titleSize = [title sizeWithFont:[UIFont systemFontOfSize:(CGFloat)17.0]
                                constrainedToSize:CGSizeMake(280, 2000)
                                    lineBreakMode:NSLineBreakByWordWrapping];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...