iOS development
Swift
segue
programmatically
Xcode

Creating a segue programmatically

Master System Design with Codemia

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

Introduction

In iOS development, "creating a segue programmatically" can mean two different things. Sometimes you want to trigger an existing storyboard segue from code. Other times you really just want to navigate in code by instantiating and presenting or pushing a view controller. Those are related, but they are not the same mechanism.

Trigger a Storyboard Segue from Code

If the segue already exists in Interface Builder and has an identifier, the normal code path is performSegue(withIdentifier:sender:).

swift
1import UIKit
2
3final class LoginViewController: UIViewController {
4    @IBAction private func continueTapped(_ sender: UIButton) {
5        performSegue(withIdentifier: "ShowDashboard", sender: self)
6    }
7
8    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
9        if segue.identifier == "ShowDashboard",
10           let destination = segue.destination as? DashboardViewController {
11            destination.username = "mark"
12        }
13    }
14}

This approach still uses a storyboard segue. The part that is "programmatic" is the trigger, not the segue definition itself.

That distinction matters because many developers search for a way to create an arbitrary storyboard segue object in code, when the real need is simply to initiate navigation based on runtime conditions.

Push or Present View Controllers Directly

If you are not relying on a storyboard-defined segue, the more direct solution is to instantiate the destination controller and navigate manually.

swift
1import UIKit
2
3final class LoginViewController: UIViewController {
4    @IBAction private func continueTapped(_ sender: UIButton) {
5        let storyboard = UIStoryboard(name: "Main", bundle: nil)
6        let controller = storyboard.instantiateViewController(
7            withIdentifier: "DashboardViewController"
8        ) as! DashboardViewController
9
10        controller.username = "mark"
11        navigationController?.pushViewController(controller, animated: true)
12    }
13}

This is often what people really want when they say "programmatic segue." It avoids storyboard segue wiring altogether and keeps the navigation logic in code.

For modal presentation, use present(_:animated:) instead of pushViewController.

Know Which Style Fits the App

Storyboard segues are useful when navigation is mostly static and visible in Interface Builder. Programmatic pushes and presents are often better when navigation depends on state, API responses, feature flags, or coordinator-based architecture.

The practical choice is:

  • use storyboard segues when a visual flow is helpful
  • use direct code navigation when runtime control matters more

Neither is universally better. The important part is not to mix them casually and create two competing navigation systems in the same screen.

Pass Data in the Right Place

If you use performSegue, the correct place to configure the destination is prepare(for:sender:). If you instantiate the controller yourself, configure it before pushing or presenting it.

That difference is simple but important. Developers often call performSegue and then try to mutate the destination controller afterward, which is too late or brittle. The data handoff should happen in the same navigation pattern that created the transition.

Common Pitfalls

The most common mistake is calling performSegue for a segue that exists only in the developer's mind and not in the storyboard. If the identifier is not present in Interface Builder, the app will crash.

Another issue is using force casts everywhere without being sure the storyboard identifier and controller class really match. That creates navigation code that fails only at runtime.

People also sometimes say "segue" when they really mean "push a view controller." If you are not using a storyboard segue definition, direct code navigation is the clearer term and the clearer implementation.

Summary

  • A storyboard segue can be triggered programmatically with performSegue(withIdentifier:sender:).
  • If you are not using storyboard segue definitions, instantiate the destination controller and push or present it directly.
  • Use prepare(for:sender:) for data transfer with storyboard segues.
  • Use direct property assignment before navigation when you create the destination controller in code.
  • Be clear about whether the app is using storyboard navigation, code-driven navigation, or a deliberate mix of both.

Course illustration
Course illustration

All Rights Reserved.