Définir l'interligne UILabel

Réponses:

122

Edit: Évidemment, le NSAttributedStringfera, sur iOS 6 et versions ultérieures. Au lieu d'utiliser un NSStringpour définir le texte de l'étiquette, créez un NSAttributedString, définissez des attributs dessus, puis définissez-le comme .attributedTextsur l'étiquette. Le code que vous voulez sera quelque chose comme ceci:

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;

L'ancien AttributStringWithString de NSAttributedString a fait la même chose, mais c'est maintenant obsolète.

Pour des raisons historiques, voici ma réponse initiale:

Réponse courte: vous ne pouvez pas. Pour modifier l'espacement entre les lignes de texte, vous devrez sous UILabel- classer et rouler les vôtres drawTextInRect, créer plusieurs étiquettes ou utiliser une police différente (peut-être une police modifiée pour une hauteur de ligne spécifique, voir la réponse de Phillipe).

Réponse longue: Dans le monde de l'imprimé et en ligne, l'espace entre les lignes de texte est appelé «leader» (rime avec «titre» et provient du métal de plomb utilisé il y a des décennies). Leading est une propriété en lecture seule de UIFont, qui était obsolète dans la version 4.0 et remplacée par lineHeight. Autant que je sache, il n'y a aucun moyen de créer une police avec un ensemble spécifique de paramètres tels que lineHeight; vous obtenez les polices système et toute police personnalisée que vous ajoutez, mais vous ne pouvez pas les modifier une fois installées.

Il n'y a pas non plus de paramètre d'espacement dans UILabel.

Je ne suis pas particulièrement satisfait du comportement de UILabel's tel quel, donc je suggère d'écrire votre propre sous-classe ou d'utiliser une bibliothèque tierce. Cela rendra le comportement indépendant de votre choix de police et sera la solution la plus réutilisable.

J'aurais aimé qu'il y ait plus de flexibilité UILabelet je serais heureux d'avoir tort!

AndrewS
la source
1
Je l'ai fait avec la sous-classification UILabel, essentiellement l'idée est de diviser le texte de l'étiquette en jetons, puis la longueur d'identité de chaque jeton, de créer une étiquette distincte pour chaque jeton et de l'ajouter l'un après l'autre. C'est tout.
Matrix du
3
Mensonges! ;) Vous pouvez patcher un fichier de police pour changer la hauteur de la ligne - voir ma réponse sur cette page.
Philippe
Je suis amené à croire qu'il existe un moyen de faire cela avec NSAttributedString. Si vous avez besoin d'étiquettes avec des chaînes attribuées dans la version antérieure à iOS 6, consultez OHAttributedLabel .
Spencer Williams
Faites-le avec NSAttributesString si vous utilisez iOS> = 6. Exemple
d.ennis
C'est simple et efficace.
R. Mohan
75

À partir d'ios 6, vous pouvez définir une chaîne attribuée dans le 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
la source
1
Merci! J'ajouterais que l'utilisation AttributedStringdésactive par exemple l'alignement du texte de l'étiquette, vous devez donc l'ajouter au style de paragraphe.
cyborg86pl
56

Vous pouvez contrôler l'espacement des lignes dans le storyboard:

question en double

Mike S
la source
10
Cependant, dans Xcode 6.1.1, la sélection de l'étiquette et la modification de la valeur de ligne dans le panneau attribué provoquera le scintillement du panneau et le verrouillage de l'application. Je n'ai pu quitter le panneau qu'en quittant de force Xcode.
izk
4
Bravo pour l'animation
Tieme
1
Dans la version 7.1, le panneau bascule et n'a aucun effet sur le temps d'exécution. J'ai dû le faire dans le code.
MiguelSlv
Une électricité de 440 watts a traversé mon panneau tout à l'heure;)
Sarasranglt
23

Depuis Interface Builder:

entrez la description de l'image ici

Par programme:

SWift 4

Utilisation de l'extension d'étiquette

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

Maintenant, appelez la fonction d'extension

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 en utilisant une instance d'étiquette (copiez et exécutez simplement ce code pour voir le résultat)

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
la source
Besoin de passer un seul argument lineSpacing ou multipleLineheight, ne peut pas passer les deux arguenemt sinon aucun résultat ne viendra, je pense
Arpit B Parekh
16

Ma solution était de patcher le fichier de police lui-même et de fixer définitivement sa hauteur de ligne. http://mbauman.net/geek/2009/03/15/minor-truetype-font-editing-on-a-mac/

J'ai dû modifier 'lineGap', 'ascender', 'descender' dans le bloc 'hhea' (comme dans l'exemple du blog).

Philippe
la source
Super cool! Ces outils de police OS X ont également fonctionné pour ma police OTF (bien qu'il ne spécifie que TTF ...). Ma police avait une hauteur de ligne de 1000 (!), Je l'ai changée en 0 et le tour est joué. J'avais des kilomètres et des kilomètres d'espace vide sous le texte sur chaque ligne.
Jonny
2
Je n'arrive pas à croire que ce soit la meilleure solution (sans offense!), Mais c'est de loin la plus simple. J'ai utilisé le logiciel gratuit (Windows) Type Light (et sous Font | Metrics | Advanced, vous pouvez modifier lineGap) pour modifier mes polices. Il vous permet également de «renommer» les polices, ce que je ne savais pas comment faire avec l'outil mentionné par Philippe.
Kirk Woll
C'est fantastique @Philippe! Merci pour le post!!
Robbie
Voir également ma réponse à une question similaire pour plus de détails: stackoverflow.com/a/19553827/201828
phatmann
@iamjustaprogrammer Il est de nouveau en ligne.
Matt B.
8

Ce gars a créé une classe pour obtenir la hauteur de ligne (sans utiliser CoreText, comme bibliothèque MTLabel): https://github.com/LemonCake/MSLabel

adriendenat
la source
4

J'ai trouvé des bibliothèques tierces comme celle-ci:

https://github.com/Tuszy/MTLabel

Pour être la solution la plus simple.

Derek Bredensteiner
la source
MSLabel est meilleur
trillions
2

Voici un code rapide pour vous permettre de définir l'interligne par programmation

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
la source
0

Bien sûr, la réponse de Mike ne fonctionne pas si vous passez la chaîne par programme. Dans ce cas, vous devez passer une chaîne attribuée et changer son style.

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
la source