Как контролировать межстрочный интервал в UILabel

objective-c swift xcode uilabel

198678 просмотра

22 ответа

Можно ли уменьшить разрыв между текстом, если поместить в несколько строк в UILabel? Мы можем установить рамку, размер шрифта и количество строк. Я хочу уменьшить разрыв между двумя строками на этом ярлыке.

Автор: Abhinav Источник Размещён: 17.05.2019 02:37

Ответы (22)


232 плюса

Решение

Я думал добавить что-то новое к этому ответу, так что я не чувствую себя так плохо ... Вот ответ Swift :

import Cocoa

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 40

let attrString = NSMutableAttributedString(string: "Swift Answer")
attrString.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

var tableViewCell = NSTableCellView()
tableViewCell.textField.attributedStringValue = attrString

«Краткий ответ: вы не можете. Чтобы изменить расстояние между строками текста, вам придется создать подкласс UILabel и создать свой собственный drawTextInRect или создать несколько меток».

Смотрите: Установка межстрочного интервала UILabel


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

Автор: Mazyod Размещён: 01.04.2011 01:00

377 плюса

В Xcode 6 вы можете сделать это в раскадровке:

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

Автор: Mike S Размещён: 25.09.2014 05:16

99 плюса

Начиная с iOS 6 вы можете установить атрибутивную строку для UILabel. Проверьте следующее:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:label.text];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = spacing;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, label.text.length)];

label.attributedText = attributedString;
Автор: iosMentalist Размещён: 17.04.2013 10:01

79 плюса

Решения, изложенные здесь, не работают для меня. Я нашел немного другой способ сделать это с помощью iOS 6 NSAttributeString:

myLabel.numberOfLines = 0; 
NSString* string = @"String with line one. \n Line two. \n Line three.";
NSMutableParagraphStyle *style  = [[NSMutableParagraphStyle alloc] init];
style.minimumLineHeight = 30.f;
style.maximumLineHeight = 30.f;
NSDictionary *attributtes = @{NSParagraphStyleAttributeName : style,};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:string
                                                         attributes:attributtes];   
[myLabel sizeToFit];
Автор: d.ennis Размещён: 08.10.2013 09:19

29 плюса

Я сделал это простое расширение, которое очень хорошо работает для меня:

extension UILabel {
    func setLineHeight(lineHeight: CGFloat) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = lineHeight
        paragraphStyle.alignment = self.textAlignment

        let attrString = NSMutableAttributedString()
        if (self.attributedText != nil) {
            attrString.append( self.attributedText!)
        } else {
            attrString.append( NSMutableAttributedString(string: self.text!))
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
        }
        attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
        self.attributedText = attrString
    }
}

Скопируйте это в файл, так что вы можете использовать его следующим образом

myLabel.setLineHeight(0.7)
Автор: Agustin Meriles Размещён: 29.01.2016 06:42

20 плюса

Из Интерфейсного Разработчика (Раскадровка / XIB):

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

Программный:

SWift 4

Использование расширения метки

extension UILabel {

    // Pass value for any one of both parameters and see result
    func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {

        guard let labelText = self.text else { return }

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple

        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }

        // Line spacing attribute
        attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
    }
}

Теперь вызовите функцию расширения

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"

// Pass value for any one argument - lineSpacing or lineHeightMultiple
label.setLineSpacing(lineSpacing: 2.0) .  // try values 1.0 to 5.0

// or try lineHeightMultiple
//label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0

Или используя экземпляр метки (просто скопируйте и выполните этот код, чтобы увидеть результат)

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40

// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))

// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))

label.attributedText = attrString

Свифт 3

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
label.attributedText = attrString
Автор: Krunal Размещён: 02.06.2017 09:39

19 плюса

В iOS 6 теперь есть альтернативный ответ, который заключается в том, чтобы установить атрибут метки на атрибуте с использованием NSAttributedString с соответствующими стилями абзаца. Посмотрите этот ответ переполнения стека для деталей относительно высоты строки с NSAttributedString:

Основной текст - NSAttributedString высота строки сделано правильно?

Автор: Dreamwieber Размещён: 10.10.2012 07:41

16 плюса

Вот класс, который подкласс UILabel имеет свойство высоты строки: https://github.com/LemonCake/MSLabel

Автор: Grsmto Размещён: 16.05.2012 12:01

8 плюса

В Swift и как функция, вдохновленная DarkDust

// Usage: setTextWithLineSpacing(myEpicUILabel,text:"Hello",lineSpacing:20)
func setTextWithLineSpacing(label:UILabel,text:String,lineSpacing:CGFloat)
{
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = lineSpacing

    let attrString = NSMutableAttributedString(string: text)
    attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

    label.attributedText = attrString
}
Автор: Thyselius Размещён: 26.07.2015 09:34

6 плюса

Согласно @Mike's Answer, lineHeightMultipleключевым моментом является снижение . Пример ниже, он хорошо работает для меня:

    NSString* text = label.text;
    CGFloat textWidth = [text sizeWithAttributes:@{NSFontAttributeName: label.font}].width;
    if (textWidth > label.frame.size.width) {
        NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
        paragraph.alignment = NSTextAlignmentCenter;
        paragraph.lineSpacing = 1.0f;
        paragraph.lineHeightMultiple = 0.75;     // Reduce this value !!!
        NSMutableAttributedString* attrText = [[NSMutableAttributedString alloc] initWithString:text];
        [attrText addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, text.length)];
        label.attributedText = attrText;
    }
Автор: isaacselement Размещён: 16.11.2015 10:45

5 плюса

SWIFT 3 полезное расширение для более удобного задания расстояния между строками :)

extension UILabel
{
    func setLineHeight(lineHeight: CGFloat)
    {
        let text = self.text
        if let text = text 
        {

            let attributeString = NSMutableAttributedString(string: text)
            let style = NSMutableParagraphStyle()

           style.lineSpacing = lineHeight
           attributeString.addAttribute(NSParagraphStyleAttributeName,
                                        value: style,
                                        range: NSMakeRange(0, text.characters.count))

           self.attributedText = attributeString
        }
    }
}
Автор: Kevin Sabbe Размещён: 07.12.2016 03:15

2 плюса

Я нашел способ, где вы можете установить реальную высоту строки (не фактор), и он даже отображает в реальном времени в Интерфейсном Разработчике . Просто следуйте инструкциям ниже. Код написан на Swift 4 .


Шаг № 1: Создайте файл с именем DesignableLabel.swiftи вставьте следующий код:

import UIKit

@IBDesignable
class DesignableLabel: UILabel {
    @IBInspectable var lineHeight: CGFloat = 20 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.minimumLineHeight = lineHeight
            paragraphStyle.maximumLineHeight = lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: font, range: NSRange(location: 0, length: attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attrString.length))
            attributedText = attrString
        }
    }
}

Шаг № 2: Поместите объект UILabelв раскадровку / XIB и установите для него класс DesignableLabel. Подождите, пока ваш проект для сборки (сборка должна быть успешной!).

Указание класса для вашей UILabel


Шаг 3: Теперь вы должны увидеть новое свойство на панели свойств с именем «Высота строки». Просто установите значение, которое вам нравится, и вы должны увидеть результаты немедленно!

Установить высоту линии в свойствах

Автор: Dschee Размещён: 14.09.2017 02:25

1 плюс

В Swift 2.0 ...

Добавить расширение:

extension UIView {
    func attributesWithLineHeight(font: String, color: UIColor, fontSize: CGFloat, kern: Double, lineHeightMultiple: CGFloat) -> [String: NSObject] {
        let titleParagraphStyle = NSMutableParagraphStyle()
        titleParagraphStyle.lineHeightMultiple = lineHeightMultiple

        let attribute = [
            NSForegroundColorAttributeName: color,
            NSKernAttributeName: kern,
            NSFontAttributeName : UIFont(name: font, size: fontSize)!,
            NSParagraphStyleAttributeName: titleParagraphStyle
        ]
        return attribute
    }
}

Теперь просто установите ваш UILabel в качестве атрибута Text:

self.label.attributedText = NSMutableAttributedString(string: "SwiftExample", attributes: attributesWithLineHeight("SourceSans-Regular", color: UIColor.whiteColor(), fontSize: 20, kern: 2.0, lineHeightMultiple: 0.5))    

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

Автор: rab_w Размещён: 16.03.2016 08:20

1 плюс

Swift3 - в расширении UITextView или UILabel добавьте эту функцию:

Я добавил некоторый код для сохранения текущего атрибутивного текста, если вы уже используете атрибутивные строки с представлением (вместо того, чтобы перезаписывать их).

func setLineHeight(_ lineHeight: CGFloat) {
    guard let text = self.text, let font = self.font else { return }

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = 1.0
    paragraphStyle.lineHeightMultiple = lineHeight
    paragraphStyle.alignment = self.textAlignment

    var attrString:NSMutableAttributedString
    if let attributed = self.attributedText {
        attrString = NSMutableAttributedString(attributedString: attributed)
    } else {
        attrString = NSMutableAttributedString(string: text)
        attrString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, attrString.length))
    }
    attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
    self.attributedText = attrString
}
Автор: rmooney Размещён: 13.12.2016 09:58

1 плюс

Другой ответ ... Если вы передаете строку программно, вам нужно передать приписанную строку вместо обычной строки и изменить ее стиль. (IOS10)

NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:@"Your \nregular \nstring"];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:4];
[attrString addAttribute:NSParagraphStyleAttributeName
                   value:style
                   range:NSMakeRange(0, attrString.length)];
_label.attributedText = attrString;
Автор: Ricardo Mutti Размещён: 24.01.2017 09:47

1 плюс

Расширение Swift 3:

    import UIKit

extension UILabel {
    func setTextWithLineSpacing(text: String, lineHeightMultiply: CGFloat = 1.3) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiply
        paragraphStyle.alignment = .center
        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length))
        self.attributedText = attributedString
    }
}
Автор: Roman Barzyczak Размещён: 01.02.2017 10:34

0 плюса

Этот код работал для меня (ios 7 и ios 8 наверняка).

_label.numberOfLines=2;
_label.textColor=[UIColor whiteColor];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple=0.5;
paragraphStyle.alignment = NSTextAlignmentCenter;
paragraphStyle.lineSpacing = 1.0;

NSDictionary *nameAttributes=@{
                               NSParagraphStyleAttributeName : paragraphStyle,
                               NSBaselineOffsetAttributeName:@2.0
                               };


NSAttributedString *string=[[NSAttributedString alloc] initWithString:@"22m\nago" attributes:nameAttributes];
_label.attributedText=string;
Автор: daniel kilinskas Размещён: 20.07.2015 02:24

0 плюса

Это должно помочь с этим. Затем вы можете назначить свой ярлык этому пользовательскому классу в раскадровке и использовать его параметры непосредственно в свойствах:

open class SpacingLabel : UILabel {

    @IBInspectable open var lineHeight:CGFloat = 1 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = 1.0
            paragraphStyle.lineHeightMultiple = self.lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: self.text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
            self.attributedText = attrString
        }
    } 
}
Автор: Russell Warwick Размещён: 03.11.2017 02:57

0 плюса

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

@IBDesignable
class Label: UILabel {
    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        let padding = (1.0 - lineHeightMultiple) * font.pointSize
        size.height += padding
        return size
    }

    override var text: String? {
        didSet {
            updateAttributedText()
        }
    }

    @IBInspectable var lineHeightMultiple: CGFloat = 1.0 {
        didSet {
            updateAttributedText()
        }
    }

    private func updateAttributedText() {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        attributedText = NSAttributedString(string: text ?? "", attributes: [
            .font: font,
            .paragraphStyle: paragraphStyle,
            .foregroundColor: textColor
        ])
        invalidateIntrinsicContentSize()
    }
}
Автор: phatmann Размещён: 16.02.2018 10:20

0 плюса

Расширение Swift 4 label. Создание NSMutableAttributedString перед передачей в функцию на случай, если для приписанного текста требуются дополнительные атрибуты.

extension UILabel {

    func setLineHeightMultiple(to height: CGFloat, withAttributedText attributedText: NSMutableAttributedString) {

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = height
        paragraphStyle.alignment = textAlignment

        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length - 1))

        self.attributedText = attributedText
    }
}
Автор: Edward Размещён: 27.02.2018 12:02

0 плюса

Вот мое решение в быстрой. Подкласс должен работать как для атрибута attributeText и text, так и для characterSpacing + lineSpacing. Он сохраняет интервал, если установлена ​​новая строка или attributeString.

open class UHBCustomLabel : UILabel {
    @IBInspectable open var characterSpacing:CGFloat = 1 {
        didSet {
            updateWithSpacing()
        }

    }
    @IBInspectable open var lines_spacing:CGFloat = -1 {
        didSet {
            updateWithSpacing()
        }

    }
    open override var text: String? {
        set {
            super.text = newValue
            updateWithSpacing()
        }
        get {
            return super.text
        }
    }
    open override var attributedText: NSAttributedString? {
        set {
            super.attributedText = newValue
            updateWithSpacing() 
        }
        get {
            return super.attributedText
        }
    }
    func updateWithSpacing() {
        let attributedString = self.attributedText == nil ? NSMutableAttributedString(string: self.text ?? "") : NSMutableAttributedString(attributedString: attributedText!)
        attributedString.addAttribute(NSKernAttributeName, value: self.characterSpacing, range: NSRange(location: 0, length: attributedString.length))
        if lines_spacing >= 0 {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = lines_spacing
            paragraphStyle.alignment = textAlignment
            attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        }
        super.attributedText = attributedString
    }
}
Автор: Umair Размещён: 29.08.2018 07:48

-5 плюса

Как быстро-грязно-умно-простой обходной путь:

Для UILabels, у которых мало строк, вы можете вместо этого использовать stackViews.

  1. Для каждой строки напишите новый ярлык.
  2. Вставьте их в StackView. (Выберите обе метки -> Редактор -> Внедрить -> StackView
  3. Настройте SpacingStackView на желаемое количество

Обязательно сложите их вертикально . Это решение также работает для пользовательских шрифтов.

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

Автор: Honey Размещён: 28.07.2016 05:52
Вопросы из категории :
32x32