Вопрос

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

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

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

Это было полезно?

Решение

Для 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

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

[here]

Для iOS 6:

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

Как

UILineBreakModeWordWrap and UITextAlignmentCenter

устарели в iOS 6 и более поздних версиях.

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

button.titleLabel?.numberOfLines = 0

СВИФТ 3

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

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

someButton.lineBreakMode = UILineBreakModeWordWrap;

(Изменить для 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 9.3 вы можете сделать это, используя раскадровка как показано ниже,

enter image description here

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

button.titleLabel?.textAlignment = .center

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

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

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

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

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

enter image description here

Те, кто использует раскадровку Xcode 4, могут нажать кнопку, и на правой панели «Утилиты» в Инспекторе атрибутов вы увидите опцию «Разрыв строки».Выберите «Перенос по словам», и все готово.

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

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

ХТХ

Вам необходимо добавить этот код:

buttonLabel.titleLabel.numberOfLines = 0;

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

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

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

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

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

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

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

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

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

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

Примечание

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

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

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

У меня была проблема с авторазметкой, после включения многострочного результата результат был такой:
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)
            ])
    }

}

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

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

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

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

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

self.btnError.titleLabel?.textAlignment = .center

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

быстрый 4.0

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

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

В Свифт 5.0 и Хкод 10.2

Общий класс пример напиши один раз и используй все изделия

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

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        
     }
}

В вашей Вьюконтроллер позвони вот так

button.btnMultipleLines()//This is your button

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

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

[button.superview addSubview:myLabel];
myLabel.center = button.center;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top