Como controlar o espaçamento de linha na UILabel

É possível reduzir o intervalo entre o texto quando colocado em várias linhas em um UILabel ? Podemos definir o quadro, o tamanho da fonte e o número de linhas. Eu quero reduzir a diferença entre as duas linhas nesse label.

Eu pensei em adicionar algo novo a esta resposta, então eu não me sinto tão mal … Aqui está uma resposta rápida :

 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 

“Resposta curta: você não pode. Para alterar o espaçamento entre linhas de texto, você terá que subclassificar a UILabel e rolar seu próprio drawTextInRect ou criar vários labels.”

Consulte: Definir o espaçamento entre linhas UILabel


Esta é uma resposta muito antiga, e outras já adicionaram a nova e melhor maneira de lidar com isso. Por favor, veja as respostas atualizadas fornecidas abaixo.

No Xcode 6, você pode fazer isso no storyboard:

insira a descrição da imagem aqui

A partir do iOS 6, você pode definir uma string atribuída ao UILabel. Verifique o seguinte:

 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; 

As soluções declaradas aqui não funcionaram para mim. Eu encontrei uma maneira ligeiramente diferente de fazer isso com o 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]; 

Eu fiz essa extensão simples que funciona muito bem para mim:

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

Copie isso em um arquivo, então você pode usá-lo assim

 myLabel.setLineHeight(0.7) 

Há uma resposta alternativa agora no iOS 6, que é definir attributeText no label, usando um NSAttributedString com os estilos de parágrafo apropriados. Veja esta resposta de estouro de pilha para detalhes sobre a altura da linha com NSAttributedString:

Texto principal – altura da linha NSAttributedString, certo?

Aqui está uma class que subclass UILabel para ter a propriedade de altura de linha: https://github.com/LemonCake/MSLabel

Do Construtor de Interface (Storyboard / XIB):

insira a descrição da imagem aqui

Programaticamente:

Swift 4

Usando a extensão de etiqueta

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

Agora ligue para a function de extensão

 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 

Ou usando uma instância de label (apenas copie e execute este código para ver o resultado)

 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 

Em Swift e como uma function, inspirada em 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 } 

Segundo @Mike ‘s Answer, reduzir o lineHeightMultiple é o ponto chave. Exemplo abaixo, funciona bem para mim:

  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 extensão útil para definir o espaço entre as linhas com mais facilidade 🙂

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

No Swift 2.0 …

Adicione uma extensão:

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

Agora, basta definir seu UILabel como attributeText:

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

Obviamente, eu adicionei um monte de parâmetros que você pode não precisar. Brincar – sinta-se livre para rewrite o método – Eu estava procurando por isso em um monte de respostas diferentes então imaginei que eu iria postar toda a extensão no caso de ajudar alguém lá fora … -rab

Swift3 – Em uma extensão UITextView ou UILabel, adicione esta function:

Eu adicionei algum código para manter o texto atual atribuído se você já estiver usando strings atribuídas com a view (ao invés de sobrescrevê-las).

 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 } 

Outra resposta … Se você está passando a string programaticamente, você precisa passar uma string atribuída em vez de uma string regular e mudar o seu estilo. (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; 

Eu encontrei uma maneira onde você pode definir a altura da linha real (não um fator) e ainda renderiza ao vivo no Interface Builder . Apenas siga as instruções abaixo. Código está escrito em Swift 4 .


Etapa 1: crie um arquivo chamado DesignableLabel.swift e insira o seguinte código:

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

Passo # 2: Coloque um UILabel em um Storyboard / XIB e defina sua class para DesignableLabel . Aguarde o seu projeto para construir (construir deve ter sucesso!).

Especificando a classe para seu UILabel


Passo 3: Agora você deve ver uma nova propriedade no painel de propriedades chamado “Altura da linha”. Basta definir o valor que você gosta e você deve ver os resultados imediatamente!

Definir altura da linha nas propriedades

Este código funcionou para mim (ios 7 e ios 8, com certeza).

 _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; 

Swift 3 extensão:

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

Isso deve ajudar com isso. Você pode então atribuir seu label a essa class personalizada no storyboard e usar seus parâmetros diretamente nas propriedades:

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

Aqui está uma subclass de UILabel que define lineHeightMultiple e garante que a altura intrínseca seja grande o suficiente para não cortar o texto.

 @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() } } 

Extensão de etiqueta Swift 4. Criando NSMutableAttributedString antes de passar para a function, caso haja atributos extras necessários para o texto atribuído.

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

Aqui está a minha solução rápida. A subclass deve funcionar para a propriedade attributeText e text e para characterSpacing + lineSpacing. Ele mantém o espaçamento se uma nova string ou assignedString estiver definida.

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

Como uma solução alternativa rápida, simples e inteligente:

Para UILabels que não possuem muitas linhas, você pode usar stackViews.

  1. Para cada linha, escreva um novo label.
  2. Incorpore-os em um StackView (selecione os dois labels -> Editor -> Embutir em -> StackView
  3. Ajuste o Spacing do StackView para a quantidade desejada

Certifique-se de empilhá-los verticalmente . Essa solução também funciona para fonts personalizadas.

insira a descrição da imagem aqui