iOS development
UILabel
text alignment
Swift programming
user interface design

How to set top-left alignment for UILabel for iOS application?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

UILabel in UIKit centers text vertically by default — if the label's frame is taller than the text, the text sits in the middle. There is no built-in verticalAlignment property. To align text to the top-left, you have two main approaches: call sizeToFit() to shrink the label to fit its content, or subclass UILabel and override drawText(in:) to control where the text is drawn. For horizontal alignment, set textAlignment = .left. This article covers all approaches with practical examples.

Using sizeToFit() (Simplest Approach)

The easiest way to top-left align text is to let the label resize to fit its content:

swift
1let label = UILabel()
2label.text = "Hello, World!"
3label.numberOfLines = 0  // Allow multiple lines
4label.textAlignment = .left
5label.frame = CGRect(x: 20, y: 100, width: 280, height: 200)
6
7// Shrink the label to fit the text
8label.sizeToFit()
9// The label's height now matches the text height — text appears at the top

After sizeToFit(), the label's frame shrinks to exactly fit the text, so there is no extra vertical space for centering to occur. The text naturally appears at the top-left.

With Auto Layout, constrain the label to the top and leading edges without a fixed height. The label's intrinsic content size handles vertical fitting:

swift
1let label = UILabel()
2label.translatesAutoresizingMaskIntoConstraints = false
3label.text = "This text will be aligned to the top-left corner."
4label.numberOfLines = 0
5label.textAlignment = .left
6view.addSubview(label)
7
8NSLayoutConstraint.activate([
9    label.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
10    label.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
11    label.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20)
12    // No height constraint — label sizes itself to fit text
13])

Without a height constraint, the label uses its intrinsic content size. The text starts at the top because there is no extra vertical space.

Subclassing UILabel for Vertical Alignment

When the label must have a fixed height larger than its text (e.g., in a table cell), subclass UILabel to control vertical alignment:

swift
1class TopAlignedLabel: UILabel {
2    override func drawText(in rect: CGRect) {
3        guard let text = text else {
4            super.drawText(in: rect)
5            return
6        }
7
8        let size = (text as NSString).boundingRect(
9            with: CGSize(width: rect.width, height: .greatestFiniteMagnitude),
10            options: [.usesLineFragmentOrigin, .usesFontLeading],
11            attributes: [.font: font!],
12            context: nil
13        ).size
14
15        let topRect = CGRect(
16            x: rect.origin.x,
17            y: rect.origin.y,
18            width: rect.width,
19            height: ceil(size.height)
20        )
21
22        super.drawText(in: topRect)
23    }
24}
25
26// Usage
27let label = TopAlignedLabel()
28label.frame = CGRect(x: 20, y: 100, width: 280, height: 200)
29label.text = "This text appears at the top of a 200pt tall label."
30label.numberOfLines = 0
31label.textAlignment = .left

By passing a smaller rect to super.drawText(in:), the text is drawn at the top of the label instead of vertically centered.

Supporting All Vertical Alignments

Extend the subclass to support top, center, and bottom alignment:

swift
1class VerticalAlignLabel: UILabel {
2    enum VerticalAlignment {
3        case top, center, bottom
4    }
5
6    var verticalAlignment: VerticalAlignment = .top {
7        didSet { setNeedsDisplay() }
8    }
9
10    override func drawText(in rect: CGRect) {
11        var adjustedRect = rect
12
13        if verticalAlignment != .center {
14            let textSize = sizeThatFits(CGSize(width: rect.width,
15                                                height: .greatestFiniteMagnitude))
16            switch verticalAlignment {
17            case .top:
18                adjustedRect.size.height = textSize.height
19            case .bottom:
20                adjustedRect.origin.y = rect.maxY - textSize.height
21                adjustedRect.size.height = textSize.height
22            case .center:
23                break
24            }
25        }
26
27        super.drawText(in: adjustedRect)
28    }
29}
30
31// Usage
32let label = VerticalAlignLabel()
33label.verticalAlignment = .top
34label.textAlignment = .left  // Horizontal alignment
35label.frame = CGRect(x: 20, y: 100, width: 280, height: 300)
36label.numberOfLines = 0
37label.text = "Top-left aligned text in a tall label."

Using UITextView as an Alternative

UITextView naturally top-aligns its text. If you need a non-editable text display with top alignment:

swift
1let textView = UITextView()
2textView.text = "This text is naturally top-aligned."
3textView.font = UIFont.systemFont(ofSize: 16)
4textView.isEditable = false
5textView.isSelectable = false
6textView.isScrollEnabled = false
7textView.textContainerInset = .zero
8textView.textContainer.lineFragmentPadding = 0
9textView.frame = CGRect(x: 20, y: 100, width: 280, height: 200)

Setting isScrollEnabled = false makes the text view behave like a label that grows to fit its content. The text is top-aligned by default.

Using a Stack View

Another approach wraps the label in a UIStackView with top alignment:

swift
1let stackView = UIStackView()
2stackView.axis = .vertical
3stackView.alignment = .leading  // Left alignment
4stackView.distribution = .fill
5stackView.translatesAutoresizingMaskIntoConstraints = false
6view.addSubview(stackView)
7
8let label = UILabel()
9label.text = "Top-left aligned via stack view."
10label.numberOfLines = 0
11label.textAlignment = .left
12stackView.addArrangedSubview(label)
13
14// The stack view pushes the label to the top
15// Add a spacer to fill remaining space
16let spacer = UIView()
17stackView.addArrangedSubview(spacer)
18
19NSLayoutConstraint.activate([
20    stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
21    stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
22    stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
23    stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20)
24])

Common Pitfalls

  • Setting textAlignment and expecting vertical changes: textAlignment only controls horizontal alignment (.left, .center, .right, .natural). There is no built-in vertical alignment property on UILabel — you must use one of the workarounds described above.
  • Calling sizeToFit() before setting text or constraints: sizeToFit() calculates size based on the current text and font. Calling it before setting text or numberOfLines produces a zero-height label. Always configure the label fully before calling sizeToFit().
  • Forgetting numberOfLines = 0 for multi-line text: The default numberOfLines is 1, which truncates text to a single line. Set it to 0 for unlimited lines, or the label will not expand vertically to fit all the text.
  • Using a fixed height constraint with Auto Layout: If you set a height constraint on a label, Auto Layout cannot shrink it to fit the text, and the default vertical centering takes effect. Remove the height constraint or use >= constraints to let the label size to its content.
  • Not invalidating layout after changing verticalAlignment: In the custom subclass, changing verticalAlignment must trigger a redraw. Call setNeedsDisplay() in the property's didSet observer, or the label will show stale alignment until the next layout pass.

Summary

  • Set textAlignment = .left for horizontal left alignment
  • For vertical top alignment, remove fixed height constraints and let the label size to its content (preferred approach)
  • Use sizeToFit() for frame-based layouts to shrink the label to fit text
  • Subclass UILabel and override drawText(in:) when a fixed-height label must display top-aligned text
  • Consider UITextView with isEditable = false as an alternative — it top-aligns text by default
  • With Auto Layout, omit the height constraint so the label's intrinsic content size controls its height

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.