Как управлять расстоянием между строками в UILabel

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

Я думал о добавлении чего-то нового в этот ответ, поэтому я не чувствую себя так плохо … Вот быстрый ответ:

 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 

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

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


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

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

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

Начиная с 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; 

Решения, изложенные здесь, не помогли мне. Я нашел несколько другой способ сделать это с помощью 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]; 

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

 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) 

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

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

Вот class, в котором подclass UILabel имеет свойство line-height: https://github.com/LemonCake/MSLabel

Из интерфейса Builder (Storyboard / 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 

Swift 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 

В 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(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length)) label.attributedText = attrString } 

Согласно ответу lineHeightMultiple ключевым моментом является сокращение 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; } 

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

В 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

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 } 

Другой ответ … Если вы передаете строку программно, вам нужно передать атрибутную строку вместо обычной строки и изменить ее стиль. (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; 

Я нашел способ, с помощью которого можно установить реальную высоту строки (не фактор), и даже в реальном времени работает в Interface Builder . Просто следуйте приведенным ниже инструкциям. Код написан в 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 и установите его class в DesignableLabel . Подождите, пока ваш проект будет построен (assembly должна быть успешной!).

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


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

Установка высоты строки в свойствах

Этот код работал для меня (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 *[email protected]{ NSParagraphStyleAttributeName : paragraphStyle, NSBaselineOffsetAttributeName:@2.0 }; NSAttributedString *string=[[NSAttributedString alloc] initWithString:@"22m\nago" attributes:nameAttributes]; _label.attributedText=string; 

Расширение 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 } } 

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

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

Вот подclass 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() } } 

Быстрое расширение ярлыка 4. Создание 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 } } 

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

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

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

Для UILabels, которые не имеют большого количества строк, вы можете вместо этого использовать stackViews.

  1. Для каждой строки напишите новую метку.
  2. Вставьте их в StackView. (Выберите обе метки -> Editor -> Embed In -> StackView
  3. Отрегулируйте расстояние между StackView до желаемой величины

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

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

Давайте будем гением компьютера.