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

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

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

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

23 ответов


для 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. во всплывающем окне "разрыв строки" выберите "Перенос Слов"

выбранный ответ правильный, но если вы предпочитаете делать такие вещи в Interface Builder, вы можете сделать это:

pic


для IOS 6:

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

As

UILineBreakModeWordWrap and UITextAlignmentCenter

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


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

[here]


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

button.titleLabel?.numberOfLines = 0

SWIFT 3

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

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

someButton.lineBreakMode = UILineBreakModeWordWrap;

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

someButton.titleLabel.lineBreakMode = UILineBreakModeWordWrap;

левое выравнивание на iOS7 с автозапуском:

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

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

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


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


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

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

HTH


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

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

Я принял этот подход и не заметил ни одного из о проблемах сообщается с backgroundImage. Я добавил этот код в-titleRectForContentRect: подкласса UIButton, но код также может быть помещен в процедуру рисования UIButton superview, который в этом случае вы должны заменить все ссылки на 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, готовый к использованию.


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

buttonLabel.titleLabel.numberOfLines = 0;

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

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


Он отлично работает.

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

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

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

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

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

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

Примечание

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


Если вы используете auto-layout.

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

self.btnError.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping

self.btnError.titleLabel?.textAlignment = .center

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

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


swift 4.0

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

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


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

другими словами:

[button.superview addSubview:myLabel];
myLabel.center = button.center;