124

I have a label which has few lines of text and I want to increase the spacing between the lines. There are similar questions asked by others but the solutions don't solve my problems. Also my label may or may not contain paragraphs. I am new to Swift. Is there a solution using storyboard? Or only through NSAttributedString its possible?

13 Answers 13

221

Programatically add LineSpacing to your UILabel using following snippet.

Earlier Swift version

let attributedString = NSMutableAttributedString(string: "Your text") // *** Create instance of `NSMutableParagraphStyle` let paragraphStyle = NSMutableParagraphStyle() // *** set LineSpacing property in points *** paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points // *** Apply attribute to string *** attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length)) // *** Set Attributed String to your label *** label.attributedText = attributedString 

Swift 4.0

let attributedString = NSMutableAttributedString(string: "Your text") // *** Create instance of `NSMutableParagraphStyle` let paragraphStyle = NSMutableParagraphStyle() // *** set LineSpacing property in points *** paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points // *** Apply attribute to string *** attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length)) // *** Set Attributed String to your label *** label.attributedText = attributedString 

Swift 4.2

let attributedString = NSMutableAttributedString(string: "Your text") // *** Create instance of `NSMutableParagraphStyle` let paragraphStyle = NSMutableParagraphStyle() // *** set LineSpacing property in points *** paragraphStyle.lineSpacing = 2 // Whatever line spacing you want in points // *** Apply attribute to string *** attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length)) // *** Set Attributed String to your label *** label.attributedText = attributedString 
Sign up to request clarification or add additional context in comments.

6 Comments

This shows an error "Value of type 'NSAttributedString' has no member 'addAttribute' ".
We need to use NSMutableAttributedString instead NSAttributedString. I have updated asnwer.
Work with custom Fonts Also Great @ Dipen Panchasara
I don't know why but, as for me, this is only working if you set linespacing >= 1, I tried to set 0.5 / 0.75, it has no effect
No need for NSMutableAttributedString. Can use NSAttributedString(string: "Your text", attributes: [NSAttributedString.Key.paragraphStyle : paragraphStyle])
|
127

From Interface Builder:

enter image description here

Programmatically:

SWift 4 & 4.2

Using label extension

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) } // (Swift 4.2 and above) Line spacing attribute attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length)) // (Swift 4.1 and 4.0) 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 = "Set\nUILabel\nline\nspacing" // 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 = "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 

5 Comments

"NSAttributedStringKey.paragraphStyle" had error, I used "NSParagraphStyleAttributeName" instead.
@Alfi - It's difference of Swift language version. Your project's swift lang. version may be swift 3.x and here are answers for both versions. Try with Swift 3 code.
Hii @krunal, I have set Linespacing and LineHeight in Interface and I set text in UILabel Programmatically but it not working. if I add text in Interface then it work. can you please help me for this Thank You and I also set attributedText and text in UILabel but that approach is not working for me.
interface builder solution is only for static text. when we add attributed string in code , those attribute which is added from interface builder is not applied.
Works for me. But be aware that it resets any NSTextAlignment previously applied to label.
76

You can control the line spacing in storyboard.

enter image description here

Same question.

7 Comments

I actually tried this. But its not working. Also this is not useful for custom fonts.
If you are facing mis-alignment in custom fonts, try to update the ascender property as mentioned here.
Its not mis-alignment problem. I cannot select my custom font with the solution you said@pkc456
Its not mis-alignment problem. I couldnt select my custom font.But now I solved that by adding my Font through settings seperately in Attributed. But still spacing remains the same.@pkc456
This is for static text only. Try adding text programatticaly. This won't work.
|
22

Recent solution for Swift 5.0

private extension UILabel { // MARK: - spacingValue is spacing that you need func addInterlineSpacing(spacingValue: CGFloat = 2) { // MARK: - Check if there's any text guard let textString = text else { return } // MARK: - Create "NSMutableAttributedString" with your text let attributedString = NSMutableAttributedString(string: textString) // MARK: - Create instance of "NSMutableParagraphStyle" let paragraphStyle = NSMutableParagraphStyle() // MARK: - Actually adding spacing we need to ParagraphStyle paragraphStyle.lineSpacing = spacingValue // MARK: - Adding ParagraphStyle to your attributed String attributedString.addAttribute( .paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length )) // MARK: - Assign string that you've modified to current attributed Text attributedText = attributedString } } 

And the usage:

let yourLabel = UILabel() let yourText = "Hello \n world \n !" yourLabel.text = yourText yourLabel.addInterlineSpacing(spacingValue: 1.5) 

2 Comments

This of course will only work if you're using UILabel.text and not UILabel.attributedText
Working for me.
16

Swift 4 and Swift 5

extension NSAttributedString { func withLineSpacing(_ spacing: CGFloat) -> NSAttributedString { let attributedString = NSMutableAttributedString(attributedString: self) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineBreakMode = .byTruncatingTail paragraphStyle.lineSpacing = spacing attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: string.count)) return NSAttributedString(attributedString: attributedString) } } 

How to use

 let example = NSAttributedString(string: "This is Line 1 \nLine 2 \nLine 3 ").withLineSpacing(15) testLabel.attributedText = example 

Example

Comments

11

You can use this reusable extension:

extension String { func lineSpaced(_ spacing: CGFloat) -> NSAttributedString { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = spacing let attributedString = NSAttributedString(string: self, attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) return attributedString } } 

Comments

4

Dipen's answer updated for Swift 4

let attr = NSMutableAttributedString(string: today) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = 2 attr.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attr.length)) label.attributedText = attr; 

1 Comment

This is no way Swift 4.
3
extension UILabel { var spacing: CGFloat { get {return 0} set { let textAlignment = self.textAlignment let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = newValue let attributedString = NSAttributedString(string: self.text ?? "", attributes: [NSAttributedString.Key.paragraphStyle: paragraphStyle]) self.attributedText = attributedString self.textAlignment = textAlignment } } } 

let label = UILabel() label.text = "test" label.spacing = 10 

Comments

1
//Swift 4: func set(text:String, inLabel:UILabel, withLineSpacing:CGFloat, alignment:NSTextAlignment){ let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = withLineSpacing let attrString = NSMutableAttributedString(string: text) attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length)) inLabel.attributedText = attrString inLabel.textAlignment = alignment } 

Comments

1

Create LabelStyle

struct LabelStyle { let font: UIFont let fontMetrics: UIFontMetrics? let lineHeight: CGFloat? let tracking: CGFloat init(font: UIFont, fontMetrics: UIFontMetrics? = nil, lineHeight: CGFloat? = nil, tracking: CGFloat = 0) { self.font = font self.fontMetrics = fontMetrics self.lineHeight = lineHeight self.tracking = tracking } func attributes(for alignment: NSTextAlignment, lineBreakMode: NSLineBreakMode) -> [NSAttributedString.Key: Any] { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.alignment = alignment paragraphStyle.lineBreakMode = lineBreakMode var baselineOffset: CGFloat = .zero if let lineHeight = lineHeight { let lineHeightMultiple = lineHeight / font.lineHeight paragraphStyle.lineHeightMultiple = lineHeightMultiple baselineOffset = 1 / lineHeightMultiple let scaledLineHeight: CGFloat = fontMetrics?.scaledValue(for: lineHeight) ?? lineHeight paragraphStyle.minimumLineHeight = scaledLineHeight paragraphStyle.maximumLineHeight = scaledLineHeight } return [ NSAttributedString.Key.paragraphStyle: paragraphStyle, NSAttributedString.Key.kern: tracking, NSAttributedString.Key.baselineOffset: baselineOffset, NSAttributedString.Key.font: font ] } } 

Create custom Label class and use our style

public class Label: UILabel { var style: LabelStyle? { nil } public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) if previousTraitCollection?.preferredContentSizeCategory != traitCollection.preferredContentSizeCategory { updateText() } } convenience init(text: String?, textColor: UIColor) { self.init() self.text = text self.textColor = textColor } override init(frame: CGRect) { super.init(frame: frame) commonInit() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) commonInit() updateText() } private func commonInit() { font = style?.font adjustsFontForContentSizeCategory = true } private func updateText() { text = super.text } public override var text: String? { get { guard style?.attributes != nil else { return super.text } return attributedText?.string } set { guard let style = style else { super.text = newValue return } guard let newText = newValue else { attributedText = nil super.text = nil return } let attributes = style.attributes(for: textAlignment, lineBreakMode: lineBreakMode) attributedText = NSAttributedString(string: newText, attributes: attributes) } } } 

Create concrete Label

public final class TitleLabel { override var style: LabelStyle? { LabelStyle( font: UIFont.Title(), lineHeight: 26.21, tracking: 0.14 ) } } 

and use it

@IBOutlet weak var titleLabel: TitleLabel! 

Comments

0

In addition to using attributed strings & paragraph styles, for small adjustemnts, font descriptors can also come in handy.

For instance:

let font: UIFont = .init( descriptor: UIFontDescriptor .preferredFontDescriptor(withTextStyle: .body) .withSymbolicTraits(.traitLooseLeading)!, size: 0 ) 

This will create a font with a looser leading, resulting in a text with a slightly larger line height (it adds 2 points) than the default system font. traitTightLeading can also be used for the opposite effect (it reduces the leading of the font by 2 points).

I wrote a blog post comparing the approaches here: https://bootstragram.com/blog/line-height-with-uikit/.

Comments

0

This solution worked for swift 5 this is reference to answer of https://stackoverflow.com/a/62116213/13171606

I Made some changes for "NSMutableAttributedString" and included the full example, i think it will help u all

Note: Please Adjust Color and Font style if found any error.

Extension

extension NSAttributedString { func withLineSpacing(_ spacing: CGFloat) -> NSMutableAttributedString { let attributedString = NSMutableAttributedString(attributedString: self) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineBreakMode = .byTruncatingTail paragraphStyle.lineSpacing = spacing attributedString.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: string.count)) return NSMutableAttributedString(attributedString: attributedString) } } 

Implementation Example

let myAttributedText = NSMutableAttributedString(string: "Please enter the required details to change your AAAAAAAAA AAAAA AAAAA. Maximum AAAAA can be AAA AA AAA AA.\n\nNote: If you do not have a AAAAA AAAA then please AAAAAAA us at 111-111-111 or send us an email AAAA AAAA AAA AAAAAAAAAA AAAAA address at xxxxxxxxxxxxxxxxxxxxxxxxxxxx.", attributes: [ .font: UIFont.systemFont(ofSize: 14), .foregroundColor: UIColor.gray, .kern: 0.0]).withLineSpacing(8) myAttributedText.addAttributes([ .font: UIFont.systemFont(ofSize: 14), .foregroundColor: UIColor.blue], range: NSRange(location: 174, length: 11)) myAttributedText.addAttributes([ .font: UIFont.systemFont(ofSize: 14), .foregroundColor: UIColor.blue], range: NSRange(location: 248, length: 28)) 

UILable

let myLabel: UILabel = { let label = UILabel() label.textAlignment = .left label.numberOfLines = 0 label.attributedText = myAttributedText //Here is your Attributed String return label }() 

Comments

-1
@discardableResult func lineHeight(_ lineHeightMultiple: CGFloat) -> Self { guard let labelText = text else { return self} let fontHeight = font.lineHeight let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = fontHeight * (lineHeightMultiple - 1) let attributedString = NSMutableAttributedString(string: labelText) attributedString.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length)) attributedText = attributedString return self } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.