UILabel
Touch Event
IBAction
iOS Development
Swift Programming

Handling Touch Event in UILabel and hooking it up to an IBAction

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 meant to render text, not act like a control. That is why taps on a label do nothing until you explicitly enable interaction and attach some gesture-handling code. The usual fix is simple, but the right implementation depends on whether the label is only a one-off tappable element or whether it is really behaving like a button.

Core Sections

Why a label ignores taps by default

UIKit disables interaction on UILabel by default through isUserInteractionEnabled = false. This protects labels from intercepting touches that should go to surrounding views, but it also means there is no automatic equivalent to connecting a button directly to an IBAction.

If you want a label to respond, the minimum setup is:

  1. Enable user interaction.
  2. Add a recognizer or custom touch handling.
  3. Route the event into a method on the view controller or the label itself.

That first step is the one developers miss most often.

Use a tap gesture recognizer for normal UIKit code

For most screens, a UITapGestureRecognizer is the cleanest solution. It keeps the label as a display view while still allowing tap behavior.

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    @IBOutlet private weak var termsLabel: UILabel!
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        termsLabel.isUserInteractionEnabled = true
10
11        let tapRecognizer = UITapGestureRecognizer(
12            target: self,
13            action: #selector(handleTermsTap(_:))
14        )
15        termsLabel.addGestureRecognizer(tapRecognizer)
16    }
17
18    @objc private func handleTermsTap(_ recognizer: UITapGestureRecognizer) {
19        print("Terms label tapped")
20    }
21}

This is not wired as an IBAction from the label itself, but the selector method plays the same practical role: it is the action endpoint that runs when the user taps.

Connecting the behavior from Interface Builder

You can set up the label in a storyboard and still keep the action code clean. Create an outlet for the label, turn on user interaction in code or in Interface Builder, and either add the recognizer in code or drag a Tap Gesture Recognizer onto the label in the scene.

If the recognizer is created in Interface Builder, the action method can be declared like this:

swift
@IBAction private func handleTermsTap(_ sender: UITapGestureRecognizer) {
    print("Tapped from storyboard recognizer")
}

The important detail is that the recognizer owns the action connection, not the UILabel. A label has no built-in touch-up-inside event like UIButton does.

When subclassing is the better design

If you have many tappable labels in the app, repeating recognizer setup in every controller gets noisy. In that case, a small subclass can centralize the interaction logic.

swift
1import UIKit
2
3final class TappableLabel: UILabel {
4    var onTap: (() -> Void)?
5
6    override init(frame: CGRect) {
7        super.init(frame: frame)
8        configureTapHandling()
9    }
10
11    required init?(coder: NSCoder) {
12        super.init(coder: coder)
13        configureTapHandling()
14    }
15
16    private func configureTapHandling() {
17        isUserInteractionEnabled = true
18        let recognizer = UITapGestureRecognizer(target: self, action: #selector(didTapLabel))
19        addGestureRecognizer(recognizer)
20    }
21
22    @objc private func didTapLabel() {
23        onTap?()
24    }
25}

A view controller can then assign behavior without rebuilding the recognizer each time:

swift
label.onTap = {
    print("Reusable tappable label fired")
}

That pattern works well if the label is part of a reusable component or a design system.

Consider whether a button is the real control

A label that looks interactive is often better implemented as a UIButton styled to look like text. A button gives you accessibility traits, focus behavior, highlight state, and clearer semantics for VoiceOver with less custom work.

swift
1let textButton = UIButton(type: .system)
2textButton.setTitle("Open privacy policy", for: .normal)
3textButton.contentHorizontalAlignment = .left
4textButton.addTarget(self, action: #selector(openPrivacyPolicy), for: .touchUpInside)

If the element is meant to perform an action, a button is the more honest control. Use a tappable label when the design truly needs inline text behavior or when the label is only augmenting a richer text layout.

Common Pitfalls

  • Forgetting to set isUserInteractionEnabled to true leaves the recognizer attached but ineffective.
  • Connecting an IBAction directly to the label instead of to a UITapGestureRecognizer will not work because UILabel does not emit control events.
  • Adding the recognizer to a parent view by mistake can make it seem like the label is unresponsive or trigger in a larger area than intended.
  • Using a label for primary actions can hurt accessibility unless you add traits, hints, and a clear touch target.
  • Enabling tap handling on a label with long attributed text may require extra hit-testing logic if only part of the text should be interactive.

Summary

  • 'UILabel ignores touches by default because user interaction is disabled.'
  • The standard solution is to enable interaction and attach a UITapGestureRecognizer.
  • In storyboard-based code, the recognizer action method is the correct equivalent of an action handler.
  • A subclass is useful when tappable-label behavior must be reused across screens.
  • If the element is truly a control, a styled UIButton is often the better design.

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.