UIButton с двумя строками текста в заголовке (numberOfLines = 2)


86

Я пытаюсь создать объект UIButtonс двумя строками текста в заголовкеLabel. Это код, который я использую:

    UIButton *titleButton = [[UIButton alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleButton.titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    [titleButton setTitle:@"This text is very long and should get truncated at the end of the second line" forState:UIControlStateNormal];
    titleButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    titleButton.titleLabel.numberOfLines = 2;
    [self addSubview:titleButton];

Когда я пробую это сделать, текст появляется только в одной строке. Кажется, единственный способ получить более одной строки текста UIButton.titleLabel- это установить numberOfLines=0и использовать UILineBreakModeWordWrap. Но это не гарантирует, что текст будет ровно двумя строками.

Однако использование равнины UILabelдействительно работает:

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
    titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
    titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
    titleLabel.numberOfLines = 2;
    titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    [self addSubview:titleLabel];

Кто-нибудь знает, как сделать UIButtonработу с двумя строчками? Единственное решение - создать отдельный UILabelтекст для хранения и добавить его в качестве подпредставления кнопки?


1
Вы видели это ? - stackoverflow.com/questions/604632/…
Viraj

Вирадж, да, если установить numberOfLines=0и использовать UILineBreakModeWordWrap, можно получить несколько строк. Проблема в том, что если текст будет слишком длинным, он может дать больше двух строк. Мне нужно ровно два одиночных символа с точками в конце второй строки (если текст слишком длинный).
маркетолог

О, тогда я думаю, что добавление subview может быть единственным выходом.
Viraj

Ответы:


87

Обновленный ответ для более поздних версий iOS

Поскольку это принятый ответ, здесь добавлен ответ @Son:

Установите эти свойства в titleLabel вашей кнопки.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2; // if you want unlimited number of lines put 0

Swift 3 и 4:

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.numberOfLines = 2 // if you want unlimited number of lines put 0

Оригинальный ответ для более старой версии iOS

Если вы хотите, чтобы наверху были две строки текста, UIButtonвы должны добавить UIlabelповерх них именно это.

UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 10, frame.size.width-100, 100)];
titleLabel.font = [UIFont boldSystemFontOfSize:24.0];
titleLabel.text = @"This text is very long and should get truncated at the end of the second line";
titleLabel.numberOfLines = 2;
titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
[myButton addSubview:titleLabel]; //add label to button instead.

Обновлено для решения для построения интерфейсов

Добавлен ответ @Borut Tomazin для более полного ответа. Обновил эту часть еще раз, так как ответ @Borut Tomazin был улучшен.

Вы можете сделать это намного проще, без кода. В Interface Builder установите Line Breakдля UIButton значение Word Wrap. Затем вы можете вставить несколько строк заголовка. Просто нажимайте Option + Returnклавиши, чтобы создать новую строку. Вам также нужно будет добавить это к определяемому пользователем атрибуту времени выполнения в Interface Builder:

titleLabel.textAlignment Number [1]

5
UILineBreakModeустарели, используйте NSLineBreakModeвместо него
guillaume

2
В последних версиях iOS в этом нет необходимости. См. Ответ @sean.
cbowns

146

Вам не нужно добавлять UILabel в UIButton. Вот только лишние предметы и работа.

Установите эти свойства в titleLabel вашей кнопки.

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.numberOfLines = 2;//if you want unlimited number of lines put 0

Swift:

button.titleLabel!.lineBreakMode = NSLineBreakMode.ByWordWrapping
button.titleLabel!.numberOfLines = 2//if you want unlimited number of lines put 0

6
Это 2013 год и на сегодняшний день это самое современное решение.
Клаас

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

@bpapa Да, я согласен, раскадровки должны быть более гибкими.
Blip

6
Это работает для меня, однако это нарушает поведение кнопки по умолчанию intrinsicContentSize, которое по-прежнему возвращает высоту, соответствующую только одной строке текста. Я исправил это, переопределив кнопку, на intrinsicContentSizeкоторой я установил высоту [self.titleLabel sizeThatFits(CGSizeMake(self.titleLabel.frame.size.width, CGFLOAT_MAX)].height.
Elise

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

88

Вы можете сделать это намного проще, без кода. В Interface Builder установите Line Breakдля UIButton значение Word Wrap. Затем вы можете вставить несколько строк заголовка. Просто нажимайте Option + Returnклавиши, чтобы создать новую строку. Вам также нужно будет добавить это к определяемому пользователем атрибуту времени выполнения в Interface Builder:

titleLabel.textAlignment Number [1]

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


1
Это решение лучше (меньше объектов, кода), чем принятое в настоящее время, для простых случаев.
Джонатан Жан

1
Вы устанавливаете те же свойства, что и программно, поэтому ваш аргумент «меньше объектов» недействителен. Код может быть меньше. Но это более читабельно.
Выбирайте

О, я думаю, неясно. Спасибо, что попытались уточнить. Не был так сильно обеспокоен тем, что это делается в IB vs Code. Больше связано с тем, что вам не нужно добавлять дополнительную метку с решением Borut, и что он также выполняет то же самое. Но да, оба отлично работают. :)
Джонатан Жан

это действительно ошеломляюще - писать код для такой простой задачи.
Джан Пойразоглу

3
Вы можете достичь той же цели на 100% без кода, добавив определяемый titleLabel.textAlignment пользователем атрибут времени выполнения в Interface Builder и установив его на Number = 1 (значение NSTextAlignmentCenter).
0xced

21
 button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;

button.titleLabel.textAlignment = NSTextAlignmentCenter;

[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

Прекрасный! Вам не нужно разделять NSStringвнутреннюю часть setTitle. WordWrapping делает это за вас!
Alex Cio

Мне пришлось разбить строку внутри заголовка набора. Без этого ничего не
вышло

9

Чтобы полностью избежать необходимости редактировать код и, следовательно, создавать подклассы вашего представления, в Xcode5 и выше вы можете следовать предложению Борута Томазина:

В Интерфейсном Разработчике (или раскадровке) установите Разрыв строки на Перенос слов. Затем вы можете вставить несколько строк заголовка. Просто нажмите клавиши Option+, Returnчтобы создать новую строку.

а затем в определяемых пользователем атрибутах времени выполнения вы можете добавить

Путь ключа: titleLabel.textAlignment
Тип: Number
Значение:1

Примечание: это может быть не полностью «перспективным», поскольку мы переводим UITextAlignmentCenterконстанту в ее числовое значение (и эта константа может измениться по мере выпуска новых версий iOS), но в ближайшем будущем это кажется безопасным.


0

Вы можете изменить необходимое значение прямо из раскадровки. Нажмите кнопку, перейдите к инспектору удостоверений и добавьте следующую пару "ключ-значение" в раздел «Пользовательские атрибуты среды выполнения»:

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.