UILabel clickable
UILabel tap action
iOS development
Swift UILabel interaction
iOS UI tutorial

How to make a UILabel clickable?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

UILabel is designed for display, not interaction, so taps are ignored unless you opt in. When you want lightweight link-like behavior without the visual weight of a button, the usual solution is to enable interaction and attach a gesture recognizer.

Make The Label Receive Touches

The first requirement is easy to miss: a label does not accept touches until isUserInteractionEnabled is set to true. After that, you can attach a UITapGestureRecognizer and route the tap to a method on your view controller.

This approach works well when the whole label should behave like one tappable element.

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    private let helpLabel: UILabel = {
5        let label = UILabel()
6        label.translatesAutoresizingMaskIntoConstraints = false
7        label.text = "Need help? Tap here."
8        label.textColor = .systemBlue
9        label.font = .preferredFont(forTextStyle: .body)
10        label.isUserInteractionEnabled = true
11        return label
12    }()
13
14    override func viewDidLoad() {
15        super.viewDidLoad()
16        view.backgroundColor = .systemBackground
17        view.addSubview(helpLabel)
18
19        NSLayoutConstraint.activate([
20            helpLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
21            helpLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor)
22        ])
23
24        let tap = UITapGestureRecognizer(target: self, action: #selector(openHelp))
25        helpLabel.addGestureRecognizer(tap)
26    }
27
28    @objc private func openHelp() {
29        let alert = UIAlertController(
30            title: "Help",
31            message: "The label tap was recognized.",
32            preferredStyle: .alert
33        )
34        alert.addAction(UIAlertAction(title: "OK", style: .default))
35        present(alert, animated: true)
36    }
37}

There are only three moving parts in that example:

  1. The label is made interactive.
  2. A tap recognizer is attached to the label.
  3. The selector handles the event.

If your label is created in Interface Builder, the same idea applies. Connect the label as an outlet, set isUserInteractionEnabled = true in viewDidLoad, then add the recognizer there.

If the label is supposed to communicate navigation, style matters. Users have learned to associate blue text, underlining, and clear spacing with links. Accessibility also matters, because a plain label does not automatically announce itself as a button.

Here is a slightly stronger version that improves both presentation and accessibility:

swift
1import UIKit
2
3final class TermsViewController: UIViewController {
4    private let termsLabel = UILabel()
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8        view.backgroundColor = .systemBackground
9
10        let text = NSAttributedString(
11            string: "Read the Terms of Service",
12            attributes: [
13                .foregroundColor: UIColor.systemBlue,
14                .underlineStyle: NSUnderlineStyle.single.rawValue
15            ]
16        )
17
18        termsLabel.translatesAutoresizingMaskIntoConstraints = false
19        termsLabel.attributedText = text
20        termsLabel.isUserInteractionEnabled = true
21        termsLabel.accessibilityTraits = [.button]
22        termsLabel.accessibilityLabel = "Read the Terms of Service"
23
24        view.addSubview(termsLabel)
25        NSLayoutConstraint.activate([
26            termsLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
27            termsLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 32)
28        ])
29
30        termsLabel.addGestureRecognizer(
31            UITapGestureRecognizer(target: self, action: #selector(showTerms))
32        )
33    }
34
35    @objc private func showTerms() {
36        print("Navigate to the terms screen")
37    }
38}

The key addition is accessibilityTraits = [.button]. Without that, VoiceOver still treats the control as static text, which makes the interaction harder to discover.

When A UILabel Is The Wrong Tool

A tappable label is useful, but it is not always the best control. If the text should behave like a standard action, a UIButton is often better because it already supports touch states, accessibility, focus handling, and content insets.

Use a label when:

  • You need inline text styling that looks like body copy.
  • The interaction is simple and the whole label is tappable.
  • You are matching an existing text-heavy layout.

Use a button when:

  • The element is a primary action.
  • You need pressed, highlighted, or disabled states.
  • The control must behave consistently across accessibility and input modes.

That tradeoff matters because many bugs around clickable labels come from rebuilding behavior that UIKit already provides elsewhere.

Common Pitfalls

The most common mistake is forgetting isUserInteractionEnabled = true. If the recognizer is attached correctly but nothing happens, check that property first.

Another frequent issue is adding the recognizer before the label instance is actually on screen, then accidentally replacing the label later. If you create a new label and assign it to the same property, the recognizer remains attached to the old object.

Layout can also cause confusion. If constraints collapse the label to a tiny frame, the tap target becomes too small. Give link-like labels enough vertical padding or surrounding whitespace so they are usable on phones.

Accessibility is another weak point. A visually styled label may look clickable but still sound like plain text to assistive technologies. Setting button traits and testing with VoiceOver avoids that problem.

Finally, do not use multiple gesture recognizers unless you really need them. A single tap recognizer is enough for most cases, and stacking recognizers on labels can create conflicts that are harder to debug than the interaction itself.

Summary

  • A UILabel becomes tappable only after isUserInteractionEnabled is enabled.
  • 'UITapGestureRecognizer is the simplest way to trigger code from a label tap.'
  • Styling and accessibility should make the label behave like an intentional interactive control.
  • For primary actions or richer states, UIButton is usually the better choice.
  • Most tap failures come from disabled interaction, tiny frames, or missing accessibility setup.

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.