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

UILabel sizeToFit/sizeThatFits игнорирует свойство numberoflines

Задача: определить размер (количество строк), который требуется UILabel, при условии, что ширина равна 300 px. Строка длиннее, поэтому я установил lineBreakMode в UILineBreakModeWordWrap и вызвал sizeThatFits, чтобы попытаться определить размер. Но он дает ширину 457 px в одной строке, а не ожидаемую 300px в двух строках.

Пожалуйста, смотрите:

CGSize available = CGSizeMake(300, INFINITY);
UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 400)] autorelease];
label.text = title;
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont fontWithName:kBoldFont size:kTitleFontSize];
label.numberOfLines = 3;
CGSize sizedtoFit = [label sizeThatFits:available];

Но я считаю, что переменная sizetoFit имеет ширину 457 пикселей и высоту 22 px, а пользовательский интерфейс отображает одну строку с обрезанным текстом. Я ожидаю ширину 300 пикселей и высоту 44 px для двух строк.

В документе UILabel для numberoflines говорится:

При изменении размера получателя с использованием метода sizeToFit изменение размера учитывает значение, сохраненное в этом свойстве. Например, если для этого свойства установлено значение 3, метод sizeToFit изменяет размер приемника так, чтобы он был достаточно большим, чтобы отображать три строки текста.

Я пробовал различные комбинации:

  • Передача CGRectZero функции init, проходящей 300x400 или 300 x бесконечность.
  • Настройка кадра после создания, а не передача его в функцию init.
  • Вызов [sizeToFit] и надеется, что он вычисляет высоту, предполагающую существующую ширину, но это не так.
  • Вызов sizeToFit, а затем вызов sizeThatFits.
  • Вызов layoutIfNeeded.

Ни один из них не работает. Что я делаю неправильно, или это плохая ошибка, когда документация и реализация структуры не согласны? Спасибо.

4b9b3361

Ответ 1

У меня была та же проблема, размер, который подходит просто игнорирует размер... /: Я закончил использование:

CGRect textSize = [UILabel textRectForBounds:CGRectMake(0, 0, 300, CGFLOAT_MAX) 
                      limitedToNumberOfLines:3];

Работает как шарм...:)

В документации говорится, что вы не должны называть его напрямую, но я использовал его некоторое время, с одобренными приложениями, и все просто потрясающе...:)

Ответ 2

Вы пробовали метод sizeWithFont: constrainedToSize: lineBreakMode:?

Например:

CGSize sizeToFit = [title sizeWithFont:label.font constrainedToSize:label.frame.size lineBreakMode:label.lineBreakMode];

Ответ 3

Я нашел, что Ian L лучше всего отвечает с помощью -sizeWithFont:constrainedToSize:lineBreakMode:, к сожалению, sizeWithFont: устарел под iOS7.

Вот как sizeWithFont: работает для подкласса UILabel в iOS7:

NSRange range = NSMakeRange(0, self.attributedText.length); 
sizeToFit = [self.text boundingRectWithSize:self.bounds.size
                                    options:NSStringDrawingUsesLineFragmentOrigin 
                                 attributes:[self.attributedText 
                          attributesAtIndex:0 effectiveRange:&range] context:nil].size;

Ответ 4

Нет решения для ios5 для sizeToFit. Вы можете использовать другие решения, такие как sizeWithFont и т.д. В ios6 проблема исправлена. Однако у меня есть это решение для моих решений:

int lineCount = myLabel.numberOfLines;
myLabel.numberOfLines = 0;
[myLabel sizeToFit];
myLabel.numberOfLines = lineCount;

И это работает. Опасайтесь, что для моей ситуации ширина моей метки исправлена, и мне нужно только sizeToFit для регулировки высоты.

Ответ 5

Я думаю, что вы получаете неожиданные результаты, потому что вы не принимаете во внимание шрифт UILabel. Попробуйте следующее:

UILabel *label = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 400)] autorelease];
label.text = title;
label.lineBreakMode = UILineBreakModeWordWrap;
label.font = [UIFont fontWithName:kBoldFont size:kTitleFontSize];
label.numberOfLines = 0;

CGSize size = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.frame.size.width,FLT_MAX) lineBreakMode:UILineBreakModeWordWrap ];
label.frame = CGRectMake(label.frame.origin.x,label.frame.origin.y,label.frame.size.width,size.height);