Swift
UIButton
iOS Development
Multiline Text
UI Design

Swift - UIButton with two lines of text

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

UIButton can display two lines of text, but only if both the title label and the layout constraints allow it. Most failures come from one of two things: the label is still configured for a single line, or the button frame is too tight for wrapped text. The fix is usually simple once you separate title configuration from layout behavior.

Core Sections

Basic Multiline Button Setup

The simplest approach is to put a newline in the title and allow multiple lines on the label:

swift
1import UIKit
2
3let button = UIButton(type: .system)
4button.setTitle("Start\nFree Trial", for: .normal)
5button.titleLabel?.numberOfLines = 0
6button.titleLabel?.lineBreakMode = .byWordWrapping
7button.titleLabel?.textAlignment = .center
8button.translatesAutoresizingMaskIntoConstraints = false

The newline guarantees two lines. numberOfLines = 0 allows wrapping instead of forcing a single line.

Auto Layout Must Leave Room for Wrapping

Many two-line button problems are not about UIButton at all. The title is configured correctly, but the button height or width prevents the label from expanding.

swift
1let container = UIView()
2container.addSubview(button)
3
4NSLayoutConstraint.activate([
5    button.centerXAnchor.constraint(equalTo: container.centerXAnchor),
6    button.centerYAnchor.constraint(equalTo: container.centerYAnchor),
7    button.widthAnchor.constraint(equalToConstant: 160),
8    button.heightAnchor.constraint(greaterThanOrEqualToConstant: 60)
9])

If you want automatic wrapping without a manual newline, a width constraint is especially important. Without width pressure, the label often stays on one long line.

Wrap Long Titles Naturally

You do not have to force a newline. If the design should wrap based on available width, use a longer title and let the label break words:

swift
1button.setTitle("Download offline map", for: .normal)
2button.titleLabel?.numberOfLines = 0
3button.titleLabel?.lineBreakMode = .byWordWrapping
4button.titleLabel?.textAlignment = .center

This works well for responsive layouts where the exact line break depends on device size.

Use Attributed Titles for Different Styles Per Line

If the first and second lines need different fonts or colors, use an attributed string:

swift
1import UIKit
2
3let button = UIButton(type: .system)
4
5let attributed = NSMutableAttributedString(
6    string: "Upgrade\n",
7    attributes: [
8        .font: UIFont.boldSystemFont(ofSize: 18),
9        .foregroundColor: UIColor.white
10    ]
11)
12
13attributed.append(NSAttributedString(
14    string: "Cancel anytime",
15    attributes: [
16        .font: UIFont.systemFont(ofSize: 12),
17        .foregroundColor: UIColor.white.withAlphaComponent(0.8)
18    ]
19))
20
21button.setAttributedTitle(attributed, for: .normal)
22button.titleLabel?.numberOfLines = 0
23button.titleLabel?.textAlignment = .center
24button.backgroundColor = .systemBlue
25button.layer.cornerRadius = 12

This gives you a headline-plus-subtitle look without building a custom control.

UIButton.Configuration on Modern iOS

On newer iOS versions, UIButton.Configuration is cleaner for basic styling:

swift
1import UIKit
2
3var config = UIButton.Configuration.filled()
4config.title = "Download\nOffline Map"
5config.baseBackgroundColor = .systemGreen
6config.baseForegroundColor = .white
7
8let button = UIButton(configuration: config)
9button.titleLabel?.numberOfLines = 0
10button.titleLabel?.textAlignment = .center

Even with configurations, multiline behavior still depends on the underlying label and constraints.

When a Custom Control Is Better

If the button needs:

  • an icon
  • title and subtitle
  • custom spacing
  • fully controlled accessibility labels

then forcing everything through setTitle becomes limiting. In that case, build a UIControl or place a UIStackView inside a button-like container instead of stretching UIButton beyond its comfortable use case.

Dynamic Type and Accessibility

Two-line buttons can become three or four lines at larger text sizes. Test with accessibility font sizes and avoid hardcoded heights that only work at the default size.

A safer setup is:

swift
button.titleLabel?.adjustsFontForContentSizeCategory = true

Then use flexible height constraints rather than fixed small frames.

State Handling Still Matters

If you use different button states, configure them intentionally:

swift
button.setTitle("Start\nFree Trial", for: .normal)
button.setTitle("Processing\nPlease wait", for: .disabled)

Otherwise the normal-state multiline title may look correct while disabled or highlighted states fall back to unexpected defaults.

Common Pitfalls

  • Setting lineBreakMode but forgetting numberOfLines.
  • Giving the button a height that clips wrapped text.
  • Expecting wrapping without a constrained width or explicit newline.
  • Styling only the normal state and ignoring disabled or highlighted states.
  • Hardcoding layout values that fail under Dynamic Type or localization.

Summary

  • Multiline UIButton titles require both label configuration and sufficient layout space.
  • Use a newline for fixed two-line titles or width constraints for natural wrapping.
  • Attributed titles are the right tool when each line needs different styling.
  • Modern UIButton.Configuration helps with styling, but not with layout by itself.
  • If the design becomes too complex, use a custom control instead of forcing UIButton to do everything.

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.