Для чего - [NSString sizeWithFont: forWidth: lineBreakMode:] подходит для? - PullRequest
38 голосов
/ 18 января 2009

На мой вопрос " Как мне заставить -[NSString sizeWithFont:forWidth:lineBreakMode:] работать? ", я узнал, что -[NSString sizeWithFont:constrainedToSize:lineBreakMode:] на самом деле было то, что мне нужно.

Документация для -[NSString sizeWithFont:forWidth:lineBreakMode:] состояний объясняет, что на самом деле текст не переносится на дополнительные строки. Так как бы я использовал это? (Примеры могут помочь.)

Ответы [ 4 ]

66 голосов
/ 18 января 2009

Отлично работает и для многострочных строк.

В основном это функция, которая позволяет вам видеть, насколько большой будет строка при визуализации с использованием шрифта и режима разрыва строки.

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

По умолчанию UILabel будет центрировать текст по вертикали. Чтобы текст был выровнен по верху, размер метки должен быть таким, чтобы она соответствовала только высоте, необходимой для строки, которая в нем находится.

Я использую этот метод для этого.

И пример того, как я бы это использовал, выглядит следующим образом:

//Calculate the expected size based on the font and linebreak mode of your label
CGSize maximumLabelSize = CGSizeMake(296,9999);

CGSize expectedLabelSize = [yourString sizeWithFont:yourLabel.font 
                        constrainedToSize:maximumLabelSize 
                        lineBreakMode:yourLabel.lineBreakMode]; 

//adjust the label the the new height.
CGRect newFrame = yourLabel.frame;
newFrame.size.height = expectedLabelSize.height;
yourLabel.frame = newFrame;

Вы указываете, насколько большой области вы должны поместить текст, а затем этот метод сообщает вам, сколько места он займет (обтекание по мере необходимости). Также, если строка выйдет за границы предоставленного вами прямоугольника, вы можете указать, а затем решили, как отобразить текст.

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

Это ответственность лейбла (или какого-либо контейнера, который вы используете для текста), чтобы выполнить перенос / что еще нужно сделать.

Надеюсь, это поможет.

Крис.

25 голосов
/ 31 июля 2009

Некоторое время я думал, что эта рутина была просто нарушена. Звучит так, будто это идеальная процедура для определения высоты фрагмента текста, когда он обернут на определенную ширину . Однако это не то, что он делает. Действительно, возвращаемая высота - это всегда одна строка. (Кстати, бессмысленно: UIFont -leading возвращает то же значение.)

Цитировать документацию на момент написания:

Несмотря на то, что он вычисляет, где произойдет разрыв строки, этот метод фактически не переносит текст на дополнительные строки; [...]

Это предложение смущало меня долгое время. Мои мысли бегали по направлениям:

  • Вычисление переносов строк, но не перенос. А?
  • Может быть, они означают, что само получение NSString не будет видоизменено, чтобы отразить разрывы строки? Но я все равно этого не ожидаю?
  • Это предложение не соответствует само по себе. У меня нет выбора, кроме как игнорировать это.

Однако оказывается, что есть смысл, который соответствует поведению, которое мы видим. Кажется, что они имеют в виду:

Эта процедура вычисляет, где произойдет разрыв строки first , и весь текст после этого игнорируется для целей вычисления ограничивающей рамки.

Поэтому возвращаемая ограничивающая рамка будет иметь высоту в одну строку и ширину до заданного максимума. (Ширина может быть меньше в зависимости от того, где вычисляется разрыв строки или если текст достаточно короткий, чтобы ему не требовалась максимальная ширина.)

Чтобы ответить на вопрос: для чего это нужно? Я не нашел ничего полезного сам по себе: только вещи, где я думал, что это будет полезно, но не было. Некоторые вещи, которые приходят на ум, однако:

  • Центрирование однострочного фрагмента текста. Я думаю, кнопки и / или названия здесь. (Хотя UILabel и UIButton могут это сделать, иногда вы хотите нарисовать это сами.)
  • Расчет границ для «извлечения» более длинного фрагмента текста. Здесь я думаю о том, где вы, возможно, захотите показать фрагмент гораздо большего фрагмента текста.
2 голосов
/ 18 января 2009

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

1 голос
/ 21 августа 2012

Вот что я придумал, применив несколько принципов из примера PyjamaSam:

AnnotationPin *myAnnotation = (AnnotationPin *)annotation;

self = [super initWithAnnotation:myAnnotation reuseIdentifier:reuseIdentifier];
self.backgroundColor = [UIColor greenColor];
self.frame = CGRectMake(0,0,30,30);
imageView = [[UIImageView alloc] initWithImage:myAnnotation.THEIMAGE];
imageView.frame = CGRectMake(3,3,20,20);
imageView.layer.masksToBounds = NO;
[self addSubview:imageView];
[imageView release];

CGSize titleSize = [myAnnotation.THETEXT sizeWithFont:[UIFont systemFontOfSize:12]];
CGRect newFrame = self.frame;
newFrame.size.height = titleSize.height + 12;
newFrame.size.width = titleSize.width + 32;
self.frame = newFrame;
self.layer.borderColor = [UIColor colorWithRed:0 green:.3 blue:0 alpha:1.0f].CGColor;
self.layer.borderWidth = 3.0;

UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(26,5,newFrame.size.width-32,newFrame.size.height-12)];
infoLabel.text = myAnnotation.title;
infoLabel.backgroundColor = [UIColor clearColor];
infoLabel.textColor = [UIColor blackColor];
infoLabel.textAlignment = UITextAlignmentCenter;
infoLabel.font = [UIFont systemFontOfSize:12];

[self addSubview:infoLabel];
[infoLabel release];

В этом примере я добавляю пользовательский вывод в класс MKAnnotation, который изменяет размер UILabel в соответствии с размером текста. Он также добавляет изображение в левой части представления, поэтому вы видите часть кода, управляющего правильным интервалом для обработки изображения и заполнения.

Ключ должен использовать CGSize titleSize = [myAnnotation.THETEXT sizeWithFont: [UIFont systemFontOfSize: 12]]; а затем переопределить размеры представления. Вы можете применить эту логику к любому представлению, но она не обрабатывает разрывы строк, как у Pyjama.

Хотя ответ Пижамы работает для некоторых, он не работает для меня. Это подробное объяснение, которое вы должны попробовать сразу перед тем, как идти куда-либо еще, если вам нужен динамический настраиваемый пин-код MKAnnotation с изображением и изменяемым размером UILabel.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...