How to control the line spacing in UILabel
Asked Answered
A

21

316

Is it possible to reduce the gap between text, when put in multiple lines in a UILabel? We can set the frame, font size and number of lines. I want to reduce the gap between the two lines in that label.

Antipode answered 31/3, 2011 at 1:50 Comment(5)
possible duplicate of How to increase a space between two lines in multiline label?Thorpe
May I suggest that you accept one of the answers that is correct for iOS 6.0 and later? The currently accepted answer is out of date.Particle
For each line use a new UILabel, then embed all labels in a StackView. Finally adjust the spacing of StackView. Remember to stack them vertically.Neurotic
Refer the following link for solution in Swift 2. https://mcmap.net/q/23524/-how-to-increase-line-spacing-in-uilabel-in-swiftPantia
Refer to https://mcmap.net/q/23496/-how-to-control-the-line-spacing-in-uilabel for storyboard tweak and other details.Wexford
I
284

I thought about adding something new to this answer, so I don't feel as bad... Here is a Swift answer:

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

"Short answer: you can't. To change the spacing between lines of text, you will have to subclass UILabel and roll your own drawTextInRect, or create multiple labels."

See: Set UILabel line spacing


This is a really old answer, and other have already addded the new and better way to handle this.. Please see the up to date answers provided below.

Ileac answered 1/4, 2011 at 13:0 Comment(10)
Since iOS 6.0, you can control it via NSAttributedString (also available in properties of UILable in Xcode's interface builder).Bailiwick
Interestingly, as near as I can tell, you can add extra spacing between the lines, but not reduce it via the NSParagraphStyle when using an NSAttributedString. (I may need to do more testing of the other modifyable properties, but the lineSpacing property only allows you to increase it.)Radnorshire
see my answer to see a way using NSAttributedStringChorister
@Radnorshire That is infuriating, and I believe you are correct. Have you found any workarounds?Shuttering
Here's what I did and it works great. This is using TTTAttributedLabel, but it should work for and AttributedString: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = 1; [mutableAttributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:whole];Carpet
Using iOS 8.2 I was able to to reduce it. You can't set it to 0, however.Neogothic
Just to clarify something in this thread. If you want to shrink the line spacing set the line height to 1.0, and then setLineHeightMultiple to a lower value < 1.0, like: [paragraphStyle setLineHeightMultiple:0.8] or paragraphStyle.lineHeightMultiple = 0.8Emotionalize
1) why are mentioning tableViewCell is there any discussion about a tableView or a cell? 2) when we are changing the layout, why don't we need to call 'setNeedsDisplay' again?Neurotic
@Honey A UI element is required to see the feature in action. Any will do. Other answers use UILabel, I used NSTextField within a NSTableCellView. Layout and drawing are separate things. setNeedsDisplay is for drawing and rendering updates.Ileac
what worked for me is this. extension UILabel { func setLineHeight(lineHeight: CGFloat) { let text = self.text if let text = text { let attributedString = NSMutableAttributedString(string: text) let style = NSMutableParagraphStyle() style.lineHeightMultiple = lineHeight attributedString.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: text.count)) self.attributedText = attributedString } } }Equiponderance
B
430

In Xcode 6 you can do this in the storyboard:

enter image description here

Bogan answered 25/9, 2014 at 17:16 Comment(14)
Take more advantages of storyboard!Areopagite
This is exactly what I needed (I needed to compress the lines). Thanks a lot!Mash
Using this option seems to break my ib every time, does anyone know what the issue could be there?Carburetor
@Carburetor have the same issue in 6.1.1. It "harlem shake" for few minutes. Doesn't know how to fix it :) Xcode ShakingJulius
Is there a way to set custom fonts this way ? I can't seem to change that helvetica neue to any other font.Lumper
This is a great solution. Unfortunately Xcode continues to disappoint . . . freezes every time I open this boxBowline
@Bowline Indeed, an unworkable solution. I've found that switching back to a plain text label will crash Xcode 6.3.2. I had to delete the label and start again.Bain
Xcode 6.3.1 when it Harlem Shakes it looks like its broken, but if you click elsewhere eventually it'll go away and all seems ok.Gorget
If you enable 'Attributed', and then open the file as source code you can edit the 'lineHeightMultiple' manually, and therefore bypass the Harlem Shake bugGorget
@Marcos it is only working in system font, there is a radar about it for several versions, at this stage customer fonts only work via the CODe and not from the interface builder.Jacinda
The shake bug is still there in Xcode 7.1.1. Careful what you do while it's shaking, Xcode will queue your clicks and keypresses and fire them all at once after it stops. I ended up having multiple source files modified and moved around. Edit the value directly in the storyboard XML to be safe until this absurd bug is fixed.Steelwork
Storyboard and I don't get along, but this is great. +1000Nievelt
@azdev for anyone still looking at this, I'm on longer getting the shakes in Xcode 7.3, but I think this is the first version where it hasn't been a problemKarli
@MarcosCurvello My solution here is a workaround that may be useful.Neurotic
I
284

I thought about adding something new to this answer, so I don't feel as bad... Here is a Swift answer:

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

"Short answer: you can't. To change the spacing between lines of text, you will have to subclass UILabel and roll your own drawTextInRect, or create multiple labels."

See: Set UILabel line spacing


This is a really old answer, and other have already addded the new and better way to handle this.. Please see the up to date answers provided below.

Ileac answered 1/4, 2011 at 13:0 Comment(10)
Since iOS 6.0, you can control it via NSAttributedString (also available in properties of UILable in Xcode's interface builder).Bailiwick
Interestingly, as near as I can tell, you can add extra spacing between the lines, but not reduce it via the NSParagraphStyle when using an NSAttributedString. (I may need to do more testing of the other modifyable properties, but the lineSpacing property only allows you to increase it.)Radnorshire
see my answer to see a way using NSAttributedStringChorister
@Radnorshire That is infuriating, and I believe you are correct. Have you found any workarounds?Shuttering
Here's what I did and it works great. This is using TTTAttributedLabel, but it should work for and AttributedString: NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = 1; [mutableAttributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:whole];Carpet
Using iOS 8.2 I was able to to reduce it. You can't set it to 0, however.Neogothic
Just to clarify something in this thread. If you want to shrink the line spacing set the line height to 1.0, and then setLineHeightMultiple to a lower value < 1.0, like: [paragraphStyle setLineHeightMultiple:0.8] or paragraphStyle.lineHeightMultiple = 0.8Emotionalize
1) why are mentioning tableViewCell is there any discussion about a tableView or a cell? 2) when we are changing the layout, why don't we need to call 'setNeedsDisplay' again?Neurotic
@Honey A UI element is required to see the feature in action. Any will do. Other answers use UILabel, I used NSTextField within a NSTableCellView. Layout and drawing are separate things. setNeedsDisplay is for drawing and rendering updates.Ileac
what worked for me is this. extension UILabel { func setLineHeight(lineHeight: CGFloat) { let text = self.text if let text = text { let attributedString = NSMutableAttributedString(string: text) let style = NSMutableParagraphStyle() style.lineHeightMultiple = lineHeight attributedString.addAttribute(.paragraphStyle, value: style, range: NSRange(location: 0, length: text.count)) self.attributedText = attributedString } } }Equiponderance
F
109

Starting from iOS 6 you can set an attributed string to the UILabel. Check the following :

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;
Frieder answered 17/4, 2013 at 10:1 Comment(3)
The attributedString must be an NSMutableAttributedString (NOT NSAttributedString)Bogan
The first line code should be NSMutableAttributedString *attributedString = [NSMutableAttributedString alloc]initWithString:@"sample text"];Areopagite
The lineSpacing property of the NSMutableParagraphStyle is never negative, so the line height cannot be reduced with this approach. To answer the question, you have to use another property, see @Chorister answer.Cohn
C
84

The solutions stated here didn't work for me. I found a slightly different way to do it with the 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];
Chorister answered 8/10, 2013 at 21:19 Comment(3)
Line height is font size dependent. Line spacing is just that, line spacing. You may get things to work out by just setting min/max line height, but that's only because the current font sizes you're using aren't greater than the line height boundaries. Per the documentation: "... glyphs and graphics exceeding this height will overlap neighboring lines ... Although this limit applies to the line itself, line spacing adds extra space between adjacent lines."Perambulate
+1, If you want to reduce the spacing between lines, this is what you want to do. The real line spacing is most likely 0 by default, this is why people report you can only increase it. The problem with spacing being too big comes from the line height being too big, this is why this will get the job done 99% of the time.Isagoge
This is the only answer I could find that uses the actual line height value (instead of a ratio) common to design applications such as Photoshop, Sketch, CSS, etc.Warhead
O
43

From Interface Builder (Storyboard/XIB):

enter image description here

Programmatically:

SWift 4

Using label extension

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

Now call extension function

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

Or using label instance (Just copy & execute this code to see result)

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
Organometallic answered 2/6, 2017 at 9:39 Comment(2)
Add the line " paragraphStyle.alignment = self.textAlignment" to keep the original alignment . Otherwise, the text will be left aligned.Zosima
For anyone loosing ellipsis on large texts, then use: paragraphStyle.lineBreakMode = .byTruncatingTailZellazelle
S
40

I've made this simple extension that works very well for me:

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

Copy this in a file, so then you can use it like this

myLabel.setLineHeight(0.7)
Somatology answered 29/1, 2016 at 18:42 Comment(8)
remember if you doing this while you are also using Storyboard for this label, then be sure to set your label's lines to 0Neurotic
Why don't you just directly set the lineSpacing and forget about setting lineHeightMultiple?Neurotic
Because the key to reduce the line height is 'lineHeightMultiple', no lineSpacingSomatology
say you want your line height to be 1.4, why can't you just write .lineSpacing = 1.4 and forget all about .lineHeightMultiple...Neurotic
Hah! I tried, and I didn't work, but I wonder why I don't see other answers here not using your mechanism, I mean they just directly set the lineSpacing. See the accepted answer...Neurotic
This seems to push my uilabel downwards when i put it in a stackview- anyone have a working project?Everyone
You saved me friend :)Sigismond
It works, but you have to make sure you've already assigned text to the label. Otherwise it will crash when your code tries to unwrap the text attributeCarbrey
S
19

There's an alternative answer now in iOS 6, which is to set attributedText on the label, using an NSAttributedString with the appropriate paragraph styles. See this stack overflow answer for details on line height with NSAttributedString:

Core Text - NSAttributedString line height done right?

Slogan answered 10/10, 2012 at 19:41 Comment(0)
P
16

Here is a class that subclass UILabel to have line-height property : https://github.com/LemonCake/MSLabel

Pepito answered 16/5, 2012 at 12:1 Comment(2)
This worked for me, thanks. I also tried to use MTLabel, but this one was better.Roveover
Does anyone know if MSLabel supports the '\n' character?Deadlight
D
15

In Swift and as a function, inspired by 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
}
Dirndl answered 26/7, 2015 at 21:34 Comment(0)
I
13

According @Mike 's Answer, reducing the lineHeightMultiple is the key point. Example below, it work well for me:

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;
}
Inwards answered 16/11, 2015 at 10:45 Comment(0)
T
9

SWIFT 3 useful extension for set space between lines more easily :)

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
        }
    }
}
Thetic answered 7/12, 2016 at 15:15 Comment(0)
C
5

I've found a way where you can set the real line height (not a factor) and it even renders live in Interface Builder. Just follow the instructions below. Code is written in Swift 4.


Step #1: Create a file named DesignableLabel.swift and insert the following code:

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

Step #2: Place a UILabel into a Storyboard/XIB and set its class to DesignableLabel. Wait for your project to build (build must succeed!).

Specifying the class to your UILabel


Step 3: Now you should see a new property in the properties pane named "Line Height". Just set the value you like and you should see the results immediately!

Set Line Height in properties

Cathey answered 14/9, 2017 at 14:25 Comment(1)
You don't need a subclass to do this. You can do it in a UILabel Extension and still add @IBInspectable - which is important if you already have a UILabel subclass and you don't want a weird class hierarchyDarryl
M
3

Here is a subclass of UILabel that sets lineHeightMultiple and makes sure the intrinsic height is large enough to not cut off text.

@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()
    }
}
Mesognathous answered 16/2, 2018 at 22:20 Comment(3)
extra padding must be (lineHeightMultiple - 1.0) * font.pointSize, right?Mussorgsky
The code above as-is seemed to work for me. But maybe you are right. Did you try your change? @PavelAlexeevMesognathous
No, I stick with lineSpacing instead of lineHeightMultiple :)Mussorgsky
T
2

Swift 3 extension:

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
  }
}
Treasury answered 1/2, 2017 at 10:34 Comment(1)
This solution works for me i just change paragraphStyle.alignment = .center to paragraphStyle.lineBreakMode = .byTruncatingTail paragraphStyle.baseWritingDirection = NSParagraphStyle.defaultWritingDirection(forLanguage: GeneralMethods.getSelectedLanguage().stringValue) and its automatically adopt direction according to selected language.Gunn
G
1

In Swift 2.0...

Add an extension:

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

Now, just set your UILabel as attributedText:

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

Obviously, I added a bunch of parameters that you may not need. Play around -- feel free to rewrite the method -- I was looking for this on a bunch of different answers so figured I'd post the whole extension in case it helps someone out there... -rab

Gainless answered 16/3, 2016 at 8:20 Comment(0)
P
1

Swift3 - In a UITextView or UILabel extension, add this function:

I added some code to keep the current attributed text if you are already using attributed strings with the view (instead of overwriting them).

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
}
Phasia answered 13/12, 2016 at 21:58 Comment(0)
B
1

Another answer... If you're passing the string programmatically, you need to pass a attributed string instead a regular string and change it's style.(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;
Byblow answered 24/1, 2017 at 21:47 Comment(0)
N
1

This should help with it. You can then assign your label to this custom class within the storyboard and use it's parameters directly within the properties:

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
        }
    } 
}
Nyctaginaceous answered 3/11, 2017 at 14:57 Comment(2)
This should help with it. You can then assign your label to this custom class within the storyboard and use it's parameters directly within the properties.Nyctaginaceous
please don't put content related to your answer in the comments. your answer should be helpful without having to read through the commentsLongeron
T
1

Swift 4 label extension. Creating NSMutableAttributedString before passing into function in case there are extra attributes required for the attributed text.

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
    }
}
Troutman answered 27/2, 2018 at 12:2 Comment(0)
I
0

This code worked for me (ios 7 & ios 8 for sure).

_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;
Instep answered 20/7, 2015 at 14:24 Comment(0)
C
-1

Here is my solution in swift. The subclass should work for both attributedText and text property and for characterSpacing + lineSpacing. It retains the spacing if a new string or attributedString is set.

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
    }
}
Condensation answered 29/8, 2018 at 19:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.