Свіфт - кнопка UIB з двома рядками тексту


93

Мені було цікаво, чи можна створити UIBкнопку з двома рядками тексту. Мені потрібно, щоб кожен рядок мав різний розмір шрифту. Перший рядок становитиме 17 балів, а другий - 11 балів. Я спробував возитися з тим, щоб помістити дві мітки всередину кнопки UIB, але не можу змусити їх залишатися в межах кнопки.

Я намагаюся зробити все це в конструкторі інтерфейсу користувача, а не програмно.

Дякую

Відповіді:


249

Є два запитання.

Мені було цікаво, чи можна створити UIBкнопку з двома рядками тексту

Це можливо за допомогою розкадрування або програмно.

Розкадровка:

Змініть «Режим розриву рядка» на « Переміщення символів» або « Обтікання словами» та використовуйте клавіші Alt / Option + Enter, щоб ввести новий рядок у поле заголовка UIButton.

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

Програмно:

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
}

Мені потрібно, щоб кожен рядок мав різний розмір шрифту 1

Найгірший випадок - ви можете використовувати власний UIButtonклас і додати до нього дві мітки.

Кращий спосіб - скористатися NSMutableAttributedString. Зверніть увагу, що цього можна досягти лише програмно.

Свіфт 5:

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //applying the line break mode
    textResponseButton?.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
    let buttonText: NSString = "hello\nthere"

    //getting the range to separate the button title strings
    let newlineRange: NSRange = buttonText.range(of: "\n")

    //getting both substrings
    var substring1 = ""
    var substring2 = ""

    if(newlineRange.location != NSNotFound) {
        substring1 = buttonText.substring(to: newlineRange.location)
        substring2 = buttonText.substring(from: newlineRange.location)
    }

    //assigning diffrent fonts to both substrings
    let font1: UIFont = UIFont(name: "Arial", size: 17.0)!
    let attributes1 = [NSMutableAttributedString.Key.font: font1]
    let attrString1 = NSMutableAttributedString(string: substring1, attributes: attributes1)

    let font2: UIFont = UIFont(name: "Arial", size: 11.0)!
    let attributes2 = [NSMutableAttributedString.Key.font: font2]
    let attrString2 = NSMutableAttributedString(string: substring2, attributes: attributes2)

    //appending both attributed strings
    attrString1.append(attrString2)

    //assigning the resultant attributed strings to the button
    textResponseButton?.setAttributedTitle(attrString1, for: [])
}

Старший Свіфт

@IBOutlet weak var btnTwoLine: UIButton?

override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        //applying the line break mode
        btnTwoLine?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;

        var buttonText: NSString = "hello\nthere"

        //getting the range to separate the button title strings
        var newlineRange: NSRange = buttonText.rangeOfString("\n")

        //getting both substrings
        var substring1: NSString = ""
        var substring2: NSString = ""

        if(newlineRange.location != NSNotFound) {
            substring1 = buttonText.substringToIndex(newlineRange.location)
            substring2 = buttonText.substringFromIndex(newlineRange.location)
        }

        //assigning diffrent fonts to both substrings
        let font:UIFont? = UIFont(name: "Arial", size: 17.0)
        let attrString = NSMutableAttributedString(
            string: substring1 as String,
            attributes: NSDictionary(
                object: font!,
                forKey: NSFontAttributeName) as [NSObject : AnyObject])

        let font1:UIFont? = UIFont(name: "Arial", size: 11.0)
        let attrString1 = NSMutableAttributedString(
            string: substring2 as String,
            attributes: NSDictionary(
                object: font1!,
                forKey: NSFontAttributeName) as [NSObject : AnyObject])

        //appending both attributed strings
        attrString.appendAttributedString(attrString1)

        //assigning the resultant attributed strings to the button
        btnTwoLine?.setAttributedTitle(attrString, forState: UIControlState.Normal)

    }

Вихідні дані

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


2
Чудово працює. Зараз мені цікаво, чи є спосіб відцентрувати текст на кожному рядку і чи є спосіб вставити більше місця між двома рядками.
Скотт

3
ви можете вирівняти обидва рядки тексту по центру. напишіть такий код btnTwoLine? .titleLabel? .textAlignment = NSTextAlignment.Center або зробіть це за допомогою файлу розкадровки (розділ керування-> Вирівнювання)
Shamsudheen TK

Чи можу я знати, з якою метою ставити більше рядків між ними?
Shamsudheen TK

Це залежить від розміру кнопки. Якщо кнопка велика, тоді два рядки тексту будуть знаходитися прямо посередині, з великою кількістю місця вгорі та внизу. Це не той погляд, на який я йшов.
Скотт

тут потрібно застосувати деякі хитрощі :) Ви можете додати більше рядків між ними, використовуючи декілька \ n. Я маю на увазі, "привіт \ n \ n \ nтут" дасть вам три пробіли. однак не забудьте змінити свій код var newlineRange: NSRange = buttonText.rangeOfString ("\ n \ n \ n")
Shamsudheen TK

22

Я шукав майже ту саму тему, за винятком того, що мені не потрібні два різні розміри шрифту. Якщо хтось шукає просте рішення:

    let button = UIButton()
    button.titleLabel?.numberOfLines = 0
    button.titleLabel?.lineBreakMode = .byWordWrapping
    button.setTitle("Foo\nBar", for: .normal)
    button.titleLabel?.textAlignment = .center
    button.sizeToFit()
    button.addTarget(self, action: #selector(rightBarButtonTapped), for: .allEvents)
    navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button)

12

У більшості рішень я помітив проблему, яка при переході до режиму розриву рядка до «Перенесення символів» другий рядок буде вирівняний за першим рядком

Щоб зробити всі рядки відцентрованими. просто змініть заголовок З звичайного на Атрибутивний, а потім ви зможете зробити кожен рядок центрованим

атрибутивний відцентрований заголовок


6

змініть розрив рядка на перенесення символів, виберіть свою кнопку та в інспекторі атрибутів перейдіть на розрив рядка та змініть його на перенесення символів

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


6

SWIFT 3 Синтаксис

let str = NSMutableAttributedString(string: "First line\nSecond Line")
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 17), range: NSMakeRange(0, 10))
str.addAttribute(NSFontAttributeName, value: UIFont.systemFont(ofSize: 12), range: NSMakeRange(11, 11))
button.setAttributedTitle(str, for: .normal)

2
не знаю, чому, але мені довелося додати button.titleLabel? .numberOfLines = 0
budidino

Спочатку не працював у швидкому 4. Потрібно встановити "розрив рядка" на "перенесення слів". Дякую!
Каран Алангат

оригінальна попередня відповідь наведена нижче: stackoverflow.com/a/30679547/5318223
Kiril S.

5

Я це виправив, і моє рішення це було лише в Раскадровці.

Зміни:

Він додав в Інспектор ідентичності -> Визначені користувачем атрибути виконання (ці Ключові шляхи):

  • numberOfLines = 2
  • titleLabel.textAlignment = 1

Визначені користувачем атрибути виконання

Я додав це в інспекторі атрибутів:

  • розрив рядка = перенесення слів

Перенос слів


2

Вам потрібно зробити щось із цього в коді. ви не можете встановити 2 різні шрифти в IB. Окрім зміни режиму розриву рядка на перенесення символів, вам потрібно щось подібне для встановлення заголовка,

override func viewDidLoad() {
        super.viewDidLoad()
        var str = NSMutableAttributedString(string: "First line\nSecond Line")
        str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(17), range: NSMakeRange(0, 10))
        str.addAttribute(NSFontAttributeName, value: UIFont.systemFontOfSize(12), range: NSMakeRange(11, 11))
        button.setAttributedTitle(str, forState: .Normal)

    }

1

Я думаю, один із способів це зробити за допомогою етикеток. Я зробив це, і це, здається, працює нормально. Я міг би створити це як кнопку UIB, а потім виставити мітки, я думаю. Не знаю, чи має це сенс.

    let firstLabel = UILabel()

    firstLabel.backgroundColor = UIColor.lightGrayColor()
    firstLabel.text = "Hi"
    firstLabel.textColor = UIColor.blueColor()
    firstLabel.textAlignment = NSTextAlignment.Center
    firstLabel.frame = CGRectMake(0, testButton.frame.height * 0.25, testButton.frame.width, testButton.frame.height * 0.2)
    testButton.addSubview(firstLabel)

    let secondLabel = UILabel()

    secondLabel.backgroundColor = UIColor.lightGrayColor()
    secondLabel.textColor = UIColor.blueColor()
    secondLabel.font = UIFont(name: "Arial", size: 12)
    secondLabel.text = "There"
    secondLabel.textAlignment = NSTextAlignment.Center
    secondLabel.frame = CGRectMake(0, testButton.frame.height * 0.5, testButton.frame.width, testButton.frame.height * 0.2)
    testButton.addSubview(secondLabel)

0

мій шлях:

func setButtonTitle(title: String, subtitle: String, button: UIButton){
        //applying the line break mode
        button.titleLabel?.lineBreakMode = NSLineBreakMode.byWordWrapping;
        let title = NSMutableAttributedString(string: title, attributes: Attributes.biggestLabel)
        let subtitle = NSMutableAttributedString(string: subtitle, attributes: Attributes.label)
        let char = NSMutableAttributedString(string: "\n", attributes: Attributes.biggestLabel)
        title.append(char)
        title.append(subtitle)
        button.setAttributedTitle(title, for: .normal)
    }

0

Запропоновані рішення, на жаль, не спрацювали для мене, коли я хотів мати кнопку мультилінії всередині CollectionView. Потім колега продемонстрував мені обхідний шлях, яким я хотів поділитися, якщо хтось має таку ж проблему - сподіваюся, це допоможе! Створіть клас, який успадковується від UIControl, і розширіть його міткою, яка потім буде вести себе подібно до кнопки.

class MultilineButton: UIControl {

    let label: UILabel = {
        $0.translatesAutoresizingMaskIntoConstraints = false
        $0.numberOfLines = 0
        $0.textAlignment = .center
        return $0
    }(UILabel())

    override init(frame: CGRect) {
        super.init(frame: frame)

        addSubview(label)

        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
            label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
            label.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
        ])
    }

    override var isHighlighted: Bool {
        didSet {
            backgroundColor = backgroundColor?.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
            label.textColor = label.textColor.withAlphaComponent(isHighlighted ? 0.7 : 1.0)
        }
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.