it-swarm.com.ru

Как добавить многострочный текст в UIButton?

У меня есть следующий код ...

UILabel *buttonLabel = [[UILabel alloc] initWithFrame:targetButton.bounds];
buttonLabel.text = @"Long text string";
[targetButton addSubview:buttonLabel];
[targetButton bringSubviewToFront:buttonLabel];

... идея в том, что у меня может быть многострочный текст для кнопки, но текст всегда скрыт backgroundImage UIButton. Вызов регистрации, чтобы показать подпредставления кнопки, показывает, что UILabel был добавлен, но сам текст не виден. Это ошибка в UIButton или я делаю что-то не так?

340
Owain Hunt

Для iOS 6 и выше используйте следующее, чтобы разрешить несколько строк:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
// you probably want to center it
button.titleLabel.textAlignment = NSTextAlignmentCenter; // if you want to 
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

Для iOS 5 и ниже используйте следующее, чтобы разрешить несколько строк:

button.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
// you probably want to center it
button.titleLabel.textAlignment = UITextAlignmentCenter;
[button setTitle: @"Line1\nLine2" forState: UIControlStateNormal];

2017, для iOS9 вперед ,

как правило, просто сделайте эти две вещи:

  1. выберите «Атрибутивный текст»
  2. во всплывающем окне «Разрыв строки» выберите «Перенос слов»
645
jessecurry

Выбранный ответ правильный, но если вы предпочитаете делать такие вещи в Интерфейсном Разработчике, вы можете сделать это:

pic

129
Adam Waite

Для IOS 6:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;

Как 

UILineBreakModeWordWrap and UITextAlignmentCenter

устарели в IOS 6 и далее ..

53
NiKKi

Если вы хотите добавить кнопку с заголовком, центрированным несколькими строками, установите настройки Interface Builder для кнопки:

[here]

51
user5440039

Чтобы переформулировать предложение Роджера Нолана, но с явным кодом, это общее решение:

button.titleLabel?.numberOfLines = 0
29
baudot

Свифт 3

button.titleLabel?.lineBreakMode = .byWordWrapping
button.titleLabel?.textAlignment = .center  
button.setTitle("Button\nTitle",for: .normal)
20
Md. Ibrahim Hassan

Выровняйте по левому краю на iOS7 с помощью автоматического размещения:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentLeft;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
11
neoneye

Есть гораздо более простой способ:

someButton.lineBreakMode = UILineBreakModeWordWrap;

(Изменить для iOS 3 и более поздних версий :)

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;
10
Valerii Hiora

Прежде всего, вы должны знать, что в UIButton уже есть UILabel. Вы можете установить его с помощью –setTitle:forState:.

Проблема с вашим примером состоит в том, что вам нужно установить для свойства numberOfLines UILabel значение, отличное от значения по умолчанию, равного 1. Вам также следует просмотреть свойство lineBreakMode.

7
Rog

В Xcode 9.3 вы можете сделать это с помощью storyboard, как показано ниже,

 enter image description here

Вам нужно установить заголовок кнопки textAlignment по центру

button.titleLabel?.textAlignment = .center

Вам не нужно устанавливать текст заголовка с новой строкой (\ n), как показано ниже,

button.setTitle("Good\nAnswer",for: .normal)

Просто установите заголовок,

button.setTitle("Good Answer",for: .normal)

Вот результат,

 enter image description here

5
Nazrul Islam

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

Я просто хотел добавить, что если вы используете раскадровки, вы можете нажать [Ctrl + Enter], чтобы вызвать новую строку в поле заголовка кнопки. 

НТН

4
user2338871

Для тех, кто использует раскадровку Xcode 4, вы можете нажать на кнопку, и в правой части панели утилит в разделе Инспектора атрибутов вы увидите опцию Разрыв строки. Выберите Word Wrap, и у вас все получится.

4
Jack

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

С другой стороны, с UILabel в качестве подпредставления UIButton, я довольно комфортно знаю, что сенсорные события всегда будут передаваться суперпредставлению UILabel.

Я использовал этот подход и не заметил никаких проблем, о которых сообщалось с backgroundImage. Я добавил этот код в -titleRectForContentRect: подкласса UIButton, но этот код также можно поместить в подпрограмму рисования суперпредставления UIButton, которая в этом случае заменяет все ссылки на self на переменную UIButton.

#define TITLE_LABEL_TAG 1234

- (CGRect)titleRectForContentRect:(CGRect)rect
{   
    // define the desired title inset margins based on the whole rect and its padding
    UIEdgeInsets padding = [self titleEdgeInsets];
    CGRect titleRect = CGRectMake(rect.Origin.x    + padding.left, 
                                  rect.Origin.x    + padding.top, 
                                  rect.size.width  - (padding.right + padding.left), 
                                  rect.size.height - (padding.bottom + padding].top));

    // save the current title view appearance
    NSString *title = [self currentTitle];
    UIColor  *titleColor = [self currentTitleColor];
    UIColor  *titleShadowColor = [self currentTitleShadowColor];

    // we only want to add our custom label once; only 1st pass shall return nil
    UILabel  *titleLabel = (UILabel*)[self viewWithTag:TITLE_LABEL_TAG];


    if (!titleLabel) 
    {
        // no custom label found (1st pass), we will be creating & adding it as subview
        titleLabel = [[UILabel alloc] initWithFrame:titleRect];
        [titleLabel setTag:TITLE_LABEL_TAG];

        // make it multi-line
        [titleLabel setNumberOfLines:0];
        [titleLabel setLineBreakMode:UILineBreakModeWordWrap];

        // title appearance setup; be at will to modify
        [titleLabel setBackgroundColor:[UIColor clearColor]];
        [titleLabel setFont:[self font]];
        [titleLabel setShadowOffset:CGSizeMake(0, 1)];
        [titleLabel setTextAlignment:UITextAlignmentCenter];

        [self addSubview:titleLabel];
        [titleLabel release];
    }

    // finally, put our label in original title view's state
    [titleLabel setText:title];
    [titleLabel setTextColor:titleColor];
    [titleLabel setShadowColor:titleShadowColor];

    // and return empty rect so that the original title view is hidden
    return CGRectZero;
}

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

3
jpedroso

Вы должны добавить этот код:

buttonLabel.titleLabel.numberOfLines = 0;
3
Pablo Blanco

Если вы используете автоматический макет на iOS 6, вам также может потребоваться установить свойство preferredMaxLayoutWidth:

button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
button.titleLabel.preferredMaxLayoutWidth = button.frame.size.width;
2
vially

Установка lineBreakMode в NSLineBreakByWordWrapping (либо в IB, либо в коде) делает метку кнопки многострочной, но не влияет на рамку кнопки.

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

Заметка

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

2
Varrry

Если вы используете авто-макет.

button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.numberOfLines = 2
2
Sourabh Sharma

Работает отлично.

Добавьте, чтобы использовать это с конфигурационным файлом, таким как Plist, вам нужно использовать CDATA для записи многослойного заголовка, например:

<string><![CDATA[Line1
Line2]]></string>
2
makiko_fly

У меня была проблема с автоматическим макетом, после включения многострочного результата результат был следующим:
 enter image description here
поэтому размер titleLabel не влияет на размер кнопки
Я добавил Constraints на основе contentEdgeInsets (в данном случае contentEdgeInsets был (10, 10, 10, 10)
после вызова makeMultiLineSupport():
 enter image description here
надеюсь, это поможет вам (Swift 5.0):

extension UIButton {

    func makeMultiLineSupport() {
        guard let titleLabel = titleLabel else {
            return
        }
        titleLabel.numberOfLines = 0
        titleLabel.setContentHuggingPriority(.required, for: .vertical)
        titleLabel.setContentHuggingPriority(.required, for: .horizontal)
        addConstraints([
            .init(item: titleLabel,
                  attribute: .top,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .top,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.top),
            .init(item: titleLabel,
                  attribute: .bottom,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .bottom,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.bottom),
            .init(item: titleLabel,
                  attribute: .left,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .left,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.left),
            .init(item: titleLabel,
                  attribute: .right,
                  relatedBy: .greaterThanOrEqual,
                  toItem: self,
                  attribute: .right,
                  multiplier: 1.0,
                  constant: contentEdgeInsets.right)
            ])
    }

}
1
Amir Khorsandi
self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

self.btnError.titleLabel?.textAlignment = .center

self.btnError.setTitle("Title", for: .normal)
0
Urvish Modi

В Swift 5.0 и Xcode 10.2

SharedClass пример написать один раз и использовать каждую посуду

Это ваш общий класс (например, вы используете все свойства компонентов)

import UIKit

class SharedClass: NSObject {

     static let sharedInstance = SharedClass()

     private override init() {

     }
  }

//UIButton extension
extension UIButton {
     //UIButton properties
     func btnMultipleLines() {
         titleLabel?.numberOfLines = 0
         titleLabel?.lineBreakMode = .byWordWrapping
         titleLabel?.textAlignment = .center        
     }
}

В вашем ViewController звоните, как это

button.btnMultipleLines()//This is your button
0
iOS

Прокрутите свой собственный класс кнопки. Это, безусловно, лучшее решение в долгосрочной перспективе. UIButton и другие классы UIKit очень ограничены в том, как вы можете их настраивать.

0
unwesen

Swift 4.0

btn.titleLabel?.lineBreakMode = .byWordWrapping
btn.titleLabel?.textAlignment = .center
btn.setTitle( "Line1\nLine2", for: .normal)
0
ingconti

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

extension UIButton {
    @IBInspectable var numberOfLines: Int {
        get { return titleLabel?.numberOfLines ?? 1 }
        set { titleLabel?.numberOfLines = newValue }
    }
}

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

0
Ash

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

0
Stunner