iOS development
Swift
Xcode
Interface Builder
UIKit

IBOutlet and IBAction

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

@IBOutlet and @IBAction are the two classic Interface Builder connection types in UIKit-based iOS development. One gives your code a reference to a user-interface object, and the other lets a user-interface event call into your code.

What @IBOutlet Does

An outlet is a property connected from a storyboard or XIB file to your view controller or custom view. It gives your Swift code access to a user-interface object created by Interface Builder.

Example:

swift
1import UIKit
2
3final class ProfileViewController: UIViewController {
4    @IBOutlet weak var nameLabel: UILabel!
5    @IBOutlet weak var saveButton: UIButton!
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9        nameLabel.text = "Guest"
10        saveButton.setTitle("Save", for: .normal)
11    }
12}

After the storyboard connections are made, nameLabel and saveButton refer to the actual objects loaded from the interface file.

weak is common for outlet properties in view controllers because the view hierarchy already owns those objects. Using weak helps avoid unnecessary strong reference cycles.

What @IBAction Does

An action is a method that Interface Builder can connect to a control event, such as a button tap or value change.

Example:

swift
1import UIKit
2
3final class LoginViewController: UIViewController {
4    @IBOutlet weak var statusLabel: UILabel!
5
6    @IBAction func signInTapped(_ sender: UIButton) {
7        statusLabel.text = "Signing in..."
8    }
9}

When the connected button is tapped, UIKit calls signInTapped.

The sender parameter is optional. These are all common shapes:

swift
1@IBAction func refreshTapped() { }
2
3@IBAction func refreshTapped(_ sender: UIButton) { }
4
5@IBAction func sliderChanged(_ sender: UISlider) { }

Use the version that gives you the event information you actually need.

How They Work Together

Most storyboard-based screens use both patterns together. Outlets let you read or update the interface, and actions respond to user input.

Here is a small example:

swift
1import UIKit
2
3final class CounterViewController: UIViewController {
4    @IBOutlet weak var countLabel: UILabel!
5    private var count = 0
6
7    override func viewDidLoad() {
8        super.viewDidLoad()
9        updateLabel()
10    }
11
12    @IBAction func incrementTapped(_ sender: UIButton) {
13        count += 1
14        updateLabel()
15    }
16
17    private func updateLabel() {
18        countLabel.text = "Count: \(count)"
19    }
20}

The label reference comes from @IBOutlet, and the button tap flows through @IBAction.

Interface Builder Connections in Xcode

In Xcode, you typically connect outlets and actions by control-dragging between the storyboard and the source code or the Connections Inspector.

Common patterns include:

  • connect a label to an outlet so code can update its text
  • connect a button tap to an action
  • connect text fields, switches, and sliders to either outlets, actions, or both

The key idea is that these are metadata hooks for Interface Builder. The @IBOutlet and @IBAction attributes themselves do not create UI objects or events. They expose connection points that Xcode and UIKit can wire together.

Under the Hood

@IBOutlet is mainly a marker for Interface Builder. At runtime, the nib or storyboard loader sets the property after the interface objects are instantiated.

@IBAction is also a marker, but for methods that can participate in UIKit's target-action system. When the control event occurs, UIKit sends the action message to the connected object.

That is why you use @IBOutlet on properties and @IBAction on methods. They represent different directions of communication:

  • outlet: storyboard object to code reference
  • action: user event to code callback

Common Pitfalls

The most common issue is a broken storyboard connection. If an outlet was deleted or renamed in code but still exists in the storyboard, the app may crash when the view loads.

Another mistake is assuming outlets are ready before the view hierarchy has been loaded. Access them in or after lifecycle points such as viewDidLoad, not during early object initialization.

People also overuse outlets when a control only needs to trigger behavior. If you never need to read or update the button itself, you may only need an action.

Finally, remember that these patterns belong to UIKit and Interface Builder workflows. In SwiftUI, the architecture is different and you generally do not use @IBOutlet or @IBAction.

Summary

  • '@IBOutlet connects a storyboard or XIB object to a Swift property.'
  • '@IBAction connects a control event to a Swift method.'
  • Outlets are for references; actions are for user-driven callbacks.
  • Broken connections in Interface Builder are a common source of runtime crashes.
  • These patterns are standard in UIKit, not in SwiftUI.

Course illustration
Course illustration

All Rights Reserved.