UILabel
line spacing
iOS development
Swift programming
text formatting

Set UILabel line spacing

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

UILabel has no direct plain-text line-spacing property, so spacing is controlled through attributed strings and paragraph styles. Many spacing bugs come from resetting attributed text accidentally or applying style before layout and content are final. A reusable helper pattern keeps typography consistent across app screens.

Core Sections

Apply line spacing with paragraph style

Line spacing lives in NSMutableParagraphStyle. To use it, build an attributed string and set it on label.

swift
1import UIKit
2
3func configureLabel(_ label: UILabel, text: String, spacing: CGFloat) {
4    let paragraph = NSMutableParagraphStyle()
5    paragraph.lineSpacing = spacing
6    paragraph.lineBreakMode = .byWordWrapping
7    paragraph.alignment = .natural
8
9    let attrs: [NSAttributedString.Key: Any] = [
10        .paragraphStyle: paragraph,
11        .font: label.font as Any,
12        .foregroundColor: label.textColor as Any
13    ]
14
15    label.numberOfLines = 0
16    label.attributedText = NSAttributedString(string: text, attributes: attrs)
17}

If numberOfLines remains one, spacing changes may appear ineffective for multiline content.

Build reusable extension for consistency

A UILabel extension reduces repetition and keeps style logic centralized.

swift
1import UIKit
2
3extension UILabel {
4    func applyLineSpacing(_ spacing: CGFloat, alignment: NSTextAlignment = .natural) {
5        guard let current = self.text, !current.isEmpty else { return }
6
7        let paragraph = NSMutableParagraphStyle()
8        paragraph.lineSpacing = spacing
9        paragraph.alignment = alignment
10        paragraph.lineBreakMode = .byWordWrapping
11
12        let attrs: [NSAttributedString.Key: Any] = [
13            .paragraphStyle: paragraph,
14            .font: self.font as Any,
15            .foregroundColor: self.textColor as Any
16        ]
17
18        self.numberOfLines = 0
19        self.attributedText = NSAttributedString(string: current, attributes: attrs)
20    }
21}

Use one helper for both static and dynamic labels to avoid visual drift.

Preserve existing rich text attributes

If label already contains bold ranges, links, or custom colors, replacing full attributed string can destroy formatting. In those cases, update paragraph style on mutable copy.

swift
1func updateSpacingPreservingAttributes(_ label: UILabel, spacing: CGFloat) {
2    guard let existing = label.attributedText else { return }
3
4    let mutable = NSMutableAttributedString(attributedString: existing)
5    let fullRange = NSRange(location: 0, length: mutable.length)
6
7    let paragraph = NSMutableParagraphStyle()
8    paragraph.lineSpacing = spacing
9    paragraph.lineBreakMode = .byWordWrapping
10
11    mutable.addAttribute(.paragraphStyle, value: paragraph, range: fullRange)
12    label.numberOfLines = 0
13    label.attributedText = mutable
14}

This approach is important for labels driven by markdown or rich text renderers.

Dynamic Type and accessibility implications

Line spacing that looks good at default text size may clip or crowd at larger accessibility sizes. Always test with Dynamic Type categories and long localized strings.

Recommendations:

  • use preferred fonts,
  • avoid fixed height constraints for multiline labels,
  • verify line spacing in left-to-right and right-to-left layouts.

Readable spacing is part of accessibility, not only aesthetics.

Interface Builder and runtime order

If text is set in storyboard and changed again in code, last assignment wins. A common bug is applying attributed text, then assigning plain text later, which removes spacing.

Keep final content-and-style assignment in one function so update order stays predictable.

Choosing spacing values by text style

One spacing constant for all labels is rarely ideal. Headline, body, and caption typically need different spacing to preserve visual rhythm.

A practical pattern is style map:

  • headline spacing: small or zero,
  • body spacing: moderate,
  • long form reading: larger.

Tie spacing to text style tokens in your design system.

Performance and update frequency

Attributed string creation is generally cheap for normal UI sizes. Performance issues appear when rebuilding many long labels repeatedly during scrolling. Cache styled strings when content is stable and avoid recalculating on every frame.

For list views, style once during configuration and avoid repeated mutation in layout callbacks.

Testing strategy

Add snapshot tests or UI tests for:

  • multiline line breaks,
  • Dynamic Type scaling,
  • dark mode contrast,
  • localization with long strings.

Typography regressions are easy to miss without visual checks.

Common Pitfalls

  • Expecting plain UILabel API to expose line-spacing property directly.
  • Forgetting numberOfLines = 0 for multiline text.
  • Overwriting attributed text later with plain text assignment.
  • Applying one spacing value to all text styles without readability checks.
  • Ignoring Dynamic Type and localization during typography validation.

Summary

  • Set UILabel line spacing through paragraph-style attributed text.
  • Use reusable helper methods to keep typography consistent.
  • Preserve existing rich-text attributes when updating spacing.
  • Validate spacing across Dynamic Type sizes and localization scenarios.
  • Keep assignment order deterministic so spacing is not accidentally reset.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.