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
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 6 Comments
NSMutableAttributedString instead NSAttributedString. I have updated asnwer.NSMutableAttributedString. Can use NSAttributedString(string: "Your text", attributes: [NSAttributedString.Key.paragraphStyle : paragraphStyle])From Interface Builder:

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
7 Comments
ascender property as mentioned here.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
UILabel.text and not UILabel.attributedTextSwift 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 Comments
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
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
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
//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
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
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
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
@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 } 
