Programming
Creating a segue programmatically
Navigating between different views in an iOS application is fundamental to user experience. While Storyboards offer a visual way to manage these transitions with segues, there are compelling reasons why developers often opt for creating a segue programmatically. This approach provides unparalleled flexibility, allowing for dynamic navigation decisions based on user input, data states, or complex logic that visual Storyboard segues simply cannot accommodate. Mastering programmatic segues is a critical skill for any serious iOS developer looking to build robust and adaptable applications, ensuring a smooth and intuitive flow for their users. It empowers you to control every aspect of the transition, from timing to custom animations, leading to a more polished and professional final product.
Understanding Segues and Programmatic Control
In the world of iOS development, a “segue” represents a transition from one view controller to another. Storyboard segues are defined visually, drawing lines between view controllers in the Interface Builder. They are straightforward for simple, static navigation flows. However, real-world applications often demand more sophisticated control. Imagine an app where a user’s role dictates which screen they see after login, or where a form must be validated before proceeding. In such scenarios, relying solely on Storyboard segues can become cumbersome and lead to less maintainable code.
Programmatic segues, on the other hand, provide the power to trigger these transitions directly from your code. This means you can evaluate conditions, fetch data, or perform any necessary logic before initiating a screen change. This method offers a level of dynamic control that is essential for complex application architectures. For instance, if a user attempts to access a premium feature, you can programmatically check their subscription status and, based on that, either present the feature or guide them to a subscription page. This conditional navigation is a cornerstone of responsive and intelligent app design.
The core concept involves identifying a segue by a unique identifier string, which is then used within your UIViewController subclass to trigger the transition. This decouples the navigation logic from the visual layout, promoting cleaner code and making future modifications significantly easier. According to a 2023 Stack Overflow developer survey, a significant percentage of professional iOS developers prefer programmatic UI and navigation for larger projects due to increased flexibility and testability, highlighting the industry’s move towards more code-driven solutions.
Why Choose Programmatic Segues?
Opting for creating a segue programmatically offers several significant advantages over their Storyboard counterparts. Foremost among these is unparalleled flexibility. When your navigation flow depends on runtime data, user interactions, or complex business logic, programmatic segues become indispensable. You can implement conditional navigation, where different paths are taken based on specific criteria, such as user permissions, data availability, or the completion of certain tasks. This level of dynamic control is simply not achievable with fixed Storyboard connections.
Furthermore, programmatic segues enhance the maintainability and testability of your codebase. By defining transitions in code, you centralize your navigation logic, making it easier to track, debug, and modify. This also facilitates unit testing, as you can test the navigation logic independently of the UI. For instance, you can write tests to ensure that a specific segue is performed only when certain conditions are met, improving the robustness of your application. This separation of concerns aligns with modern software engineering principles, leading to cleaner and more scalable applications.
Another key benefit is the ability to pass data effectively between view controllers. While Storyboard segues offer the prepare(for:sender:) method, programmatic segues often allow for more direct and type-safe data passing mechanisms, especially when dealing with custom initializers or dependency injection. This can lead to clearer data flow and reduce the potential for errors. For example, when displaying user profile details, you can pass a specific user ID to the destination view controller, which then fetches and displays the relevant information. This ensures that the destination view controller receives precisely the data it needs, rather than relying on global state or less explicit patterns.
- Enables complex conditional navigation paths.
- Improves code maintainability and testability.
- Facilitates direct and type-safe data passing.
- Reduces coupling between UI and business logic.
- Offers fine-grained control over transition animations.
Implementing Programmatic Segues: A Step-by-Step Guide
Implementing a programmatic segue involves a few key steps that ensure your application navigates smoothly and predictably. The process begins in your Storyboard, where you’ll define the segue and assign it a unique identifier. This identifier acts as a handle that your code will use to trigger the transition. For example, if you’re transitioning from a login screen to a dashboard, you might name your segue “showDashboard”. This initial setup is crucial for establishing the link between your visual design and your code-driven navigation.
Once the segue is configured in the Storyboard, the real power comes into play within your UIViewController subclass. You will typically call the performSegue(withIdentifier:sender:) method when a specific event occurs, such as a button tap or a successful network request. This method initiates the transition. Before the destination view controller is loaded, the prepare(for:sender:) method is called on the source view controller. This is your opportunity to pass any necessary data to the destination, ensuring it has all the information it needs to display correctly. Effective data transfer is a cornerstone of seamless user experiences.
When you need to pass data, ensure you cast the segue.destination property to the correct type of your target UIViewController. This allows you to access its properties and methods, setting up the necessary data before the transition completes. This pattern is robust and widely used in iOS development for managing data flow during navigation. Proper error handling, such as ensuring the identifier exists or that the destination controller is of the expected type, is also a best practice to prevent runtime crashes.
-
Define the Segue in Storyboard: Drag a segue from the source view controller to the destination view controller in your Storyboard. In the Attributes Inspector, give it a unique “Identifier” (e.g., “ShowDetailView”). This identifier is how you’ll refer to it in code.
-
Trigger the Segue Programmatically: In your source
UIViewController, callperformSegue(withIdentifier: "ShowDetailView", sender: self)within an action method (e.g., a button tap handler) or based on specific application logic. -
Prepare for Data Transfer: Override the
prepare(for:sender:)method in your sourceUIViewController. This method is called just before the segue is performed. Inside this method, check thesegue.identifierto ensure you’re dealing with the correct segue. -
Pass Data to Destination: Cast
segue.destinationto your specific destination view controller type. Then, access its properties to pass any necessary Question & Answer :
I have a commonUIViewControllerthat all myUIViewsControllersextend to reuse some common operations.I want to set up a segue on this “Common”
UIViewControllerso that all the otherUIViewControllersinherit.I am trying to figure out how do I do that programmatically.
I guess that the question could also be how do I set a
seguefor all myUIViewControllerswithout going into the story board and do them by hand.I thought I would add another possibility. One of the things you can do is you can connect two scenes in a storyboard using a segue that is not attached to an action, and then programmatically trigger the segue inside your view controller. The way you do this, is that you have to drag from the file’s owner icon at the bottom of the storyboard scene that is the segueing scene, and right drag to the destination scene. I’ll throw in an image to help explain.

A popup will show for “Manual Segue”. I picked Push as the type. Tap on the little square and make sure you’re in the attributes inspector. Give it an identifier which you will use to refer to it in code.

Ok, next I’m going to segue using a programmatic bar button item. In viewDidLoad or somewhere else I’ll create a button item on the navigation bar with this code:
UIBarButtonItem *buttonizeButton = [[UIBarButtonItem alloc] initWithTitle:@"Buttonize" style:UIBarButtonItemStyleDone target:self action:@selector(buttonizeButtonTap:)]; self.navigationItem.rightBarButtonItems = @[buttonizeButton];Ok, notice that the selector is buttonizeButtonTap:. So write a void method for that button and within that method you will call the segue like this:
-(void)buttonizeButtonTap:(id)sender{ [self performSegueWithIdentifier:@"Associate" sender:sender]; }The sender parameter is required to identify the button when prepareForSegue is called. prepareForSegue is the framework method where you will instantiate your scene and pass it whatever values it will need to do its work. Here’s what my method looks like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"Associate"]) { TranslationQuizAssociateVC *translationQuizAssociateVC = [segue destinationViewController]; translationQuizAssociateVC.nodeID = self.nodeID; //--pass nodeID from ViewNodeViewController translationQuizAssociateVC.contentID = self.contentID; translationQuizAssociateVC.index = self.index; translationQuizAssociateVC.content = self.content; } }I tested it and it works.