Definir espaçamento de linha UILabel

Respostas:

122

Edit: Evidentemente NSAttributedStringvai fazer isso, no iOS 6 e posterior. Em vez de usar um NSStringpara definir o texto do rótulo, crie um NSAttributedString, defina atributos nele e, em seguida, defina-o como .attributedTextno rótulo. O código que você deseja será mais ou menos assim:

NSMutableAttributedString* attrString = [[NSMutableAttributedString  alloc] initWithString:@"Sample text"];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:24];
[attrString addAttribute:NSParagraphStyleAttributeName
    value:style
    range:NSMakeRange(0, strLength)];
uiLabel.attributedText = attrString;

Old attributedStringWithString de NSAttributedString fez a mesma coisa, mas agora que está sendo preterido.

Por razões históricas, aqui está minha resposta original:

Resposta curta: você não pode. Para alterar o espaçamento entre as linhas de texto, você terá que criar uma subclasse UILabele drawTextInRectcriar seu próprio , criar vários rótulos ou usar uma fonte diferente (talvez uma editada para uma altura de linha específica, veja a resposta de Phillipe).

Resposta longa: no mundo impresso e online, o espaço entre as linhas do texto é conhecido como "líder" (rima com 'cabeçalho' e vem do metal de chumbo usado décadas atrás). Leading é uma propriedade somente leitura de UIFont, que foi descontinuada no 4.0 e substituída por lineHeight. Até onde eu sei, não há como criar uma fonte com um conjunto específico de parâmetros, como lineHeight; você obtém as fontes do sistema e qualquer fonte personalizada que adicionar, mas não pode ajustá-las depois de instaladas.

Também não há parâmetro de espaçamento em UILabel.

Não estou particularmente feliz com UILabelo comportamento de, então, sugiro escrever sua própria subclasse ou usar uma biblioteca de terceiros. Isso tornará o comportamento independente da escolha da fonte e será a solução mais reutilizável.

Eu gostaria que foi mais flexibilidade na UILabel, e eu ficaria feliz em estar errado comprovada!

AndrewS
fonte
1
Eu fiz isso com a subclassificação UILabel, basicamente a ideia é dividir o texto do rótulo em tokens e, em seguida, o comprimento da identidade de cada token, criar um rótulo separado para cada token e anexar um após o outro. É isso aí.
Matrix
3
Mentiras! ;) Você pode corrigir um arquivo de fonte para alterar a altura da linha - veja minha resposta nesta página.
Philippe
Sou levado a acreditar que há uma maneira de fazer isso com NSAttributedString. Se você precisar de rótulos com strings atribuídas antes do iOS 6, verifique OHAttributedLabel .
Spencer Williams
Faça isso com NSAttributesString se você usar iOS> = 6. Exemplo
d.ennis
Isso é simples e funciona bem.
R. Mohan
75

A partir do iOS 6, você pode definir uma string atribuída no UILabel:

NSString *labelText = @"some text"; 
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:labelText];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:40];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [labelText length])];
cell.label.attributedText = attributedString ;
iosMentalist
fonte
1
obrigado! Eu adicionaria isso usando AttributedStringdesabilita, por exemplo, o alinhamento do texto do rótulo, então você tem que adicioná-lo ao estilo de parágrafo.
cyborg86pl
56

Você pode controlar o espaçamento entre linhas no storyboard:

pergunta duplicada

Mike S
fonte
10
No entanto, no Xcode 6.1.1, selecionar o rótulo e alterar o valor da linha no painel atribuído fará com que o painel pisque e bloqueie o aplicativo. Só consegui sair do painel ao forçar o encerramento do Xcode.
izk
4
Gostei
1
Na versão 7.1, o painel se move e não tem nenhum efeito no tempo de execução. Tive que fazer isso em código.
MiguelSlv
440 watts de eletricidade passaram pelo meu painel agora;)
Sarasranglt
23

Do Interface Builder:

insira a descrição da imagem aqui

Programaticamente:

SWift 4

Usando extensão de rótulo

extension UILabel {

    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 chame a função 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 a instância do rótulo (basta copiar e executar este código para ver o resultado)

let label = UILabel()
let stringValue = "Set\nUILabel\nline\nspacing"
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 = "Set\nUILabel\nline\nspacing"
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
fonte
Preciso passar apenas em um argumento lineSpacing ou multipleLineheight, não posso passar em ambos os argumentos de outra forma, nenhum resultado virá, eu acho
Arpit B Parekh
16

Minha solução foi corrigir o próprio arquivo de fonte e fixar definitivamente a altura da linha. http://mbauman.net/geek/2009/03/15/minor-truetype-font-editing-on-a-mac/

Tive que modificar 'lineGap', 'ascender', 'descender' no bloco 'hhea' (como no exemplo do blog).

Philippe
fonte
Muito legal! Essas ferramentas de fonte do OS X também funcionaram para minha fonte OTF (embora ela apenas especifique TTF ...). Minha fonte tinha altura de linha 1000 (!), Mudei para 0 e voila. Eu tinha quilômetros e quilômetros de espaço vazio abaixo do texto em cada linha.
Jonny
2
Não posso acreditar que esta seja a melhor solução (sem ofensa!), Mas é de longe a mais simples. Usei o software gratuito (Windows) Type Light (e em Font | Metrics | Advanced você pode modificar o lineGap) para editar minhas fontes. Também permite "renomear" as fontes, o que não consegui descobrir como fazer usando a ferramenta mencionada por Philippe.
Kirk Woll
Isso é fantástico, @Philippe! Obrigado pelo post !!
Robbie
Veja também minha resposta a uma pergunta semelhante para obter mais detalhes: stackoverflow.com/a/19553827/201828
phatmann
@iamjustaprogrammer Está online novamente.
Matt B.
8

Esse cara criou uma classe para obter a altura da linha (sem usar CoreText, como biblioteca MTLabel): https://github.com/LemonCake/MSLabel

adriendenat
fonte
7

A melhor coisa que encontrei é: https://github.com/mattt/TTTAttributedLabel

É uma subclasse UILabel, então você pode simplesmente inseri-la e, em seguida, alterar a altura da linha:

myLabel.lineHeightMultiple = 0.85;
myLabel.leading = 2;
lms
fonte
4

Encontrei bibliotecas de terceiros como esta:

https://github.com/Tuszy/MTLabel

Para ser a solução mais fácil.

Derek Bredensteiner
fonte
MSLabel é melhor
trilhões de
2

Aqui está um código rápido para você definir o espaçamento de linha de forma programática

let label = UILabel()

let attributedText = NSMutableAttributedString(string: "Your string")
let paragraphStyle = NSMutableParagraphStyle()

//SET THIS:
paragraphStyle.lineSpacing = 4
//OR SET THIS:
paragraphStyle.lineHeightMultiple = 4

//Or set both :)

let range = NSMakeRange(0, attributedText.length)
attributedText.addAttributes([NSParagraphStyleAttributeName : paragraphStyle], range: range)
label.attributedText = attributedText
ullstrm
fonte
0

Claro, a resposta de Mike não funciona se você passar a string programaticamente. Neste caso você precisa passar uma string atribuída e mudar seu estilo.

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
fonte