Unwind Segues in iOS Storyboards

Introduced in 2012 with iOS 6, Unwind Segues give you a way to “unwind” the navigation stack and specify a destination to go back to. The first time you use them, they can be confusing. In fact there’s no other UI feature of iOS development that has caused more discussion in our office than Unwind Segues. In this post, I’ll help you understand the fundamentals.

Unwind exit buttonEver since I noticed the strange “Exit” outlet show up in Xcode, I’ve wondered what it did. Most people probably did what I did the first time they saw it. I Ctrl-draged from a button to the “Exit” outlet and nothing happened. This is the beginning of the confusion for new developers. How do I get the “Exit” outlet to do anything?

I’m going to setup a simple example of three UIViewControllers in a UINavigationController.

Unwind example

I put a “Next” button on each view controller that goes from 1 to 3 in order. To do this I used “Show” or “Push” Segues as you normally would to go from one view controller to the next. I want to create an Unwind Segue that goes from 3 all the way to 1. I placed a “Home” button on UIViewController #3. When pressed, I want it to unwind all the way to #1.

Enable Unwind Segues 

To enable the Unwind Segue you need to add some code first. There are two things confusing about this:

  1. It’s backwards. Normally when you create an action outlet for a button, Interface Builder will create the code for you.  In this case Ctrl-dragging from the “Home” button to the “Exit” outlet is expecting code to already be in your project.
  2. Normally when you create an action outlet for a button, it puts the code in the same class that owns the button. For Unwind Segues, you need to put the code in the destination view controller. In my simple example the code needs to go in view controller #1 even though the button that is executing the segue is in #3.

So let’s look at what code we need to write for our Unwind Segue. I assigned a custom class for UIViewController #1 and added the following function:

-(IBAction)prepareForUnwind:(UIStoryboardSegue *)segue {
}

The signature of this function is key to Interface Builder recognizing it. It must have a return value of IBAction and take one parameter of UIStoryboardSegue*. The name of the function does not matter. In fact, the function does not even have to do anything. It’s just there as a marker of which UIViewController is the destination of the Unwind Segue. Of course, you could put code in this function if you wanted to. You can inspect the identifier of the segue or access the source view controller and get at any properties you may need. The source view controller in my case would be #3.

Now that I have the code in place, I can return to Interface Builder and add our Unwind Segue.

Adding the Unwind Segue in Interface Builder

Unwind select actionThis time when you Ctrl-drag from the “Home” button to the “Exit” outlet, you will see a modal popup.

Interface Builder will search every UIViewController class in your project for functions with that particular signature and list them all in the pop-up. Select the function that we just added in the previous step. 

Now you will see the unwind segue added to the #3 view controller:

Unwind segue in document outline

And that’s all that it takes to get a simple Unwind Segue working. When you press the “Home” button, the runtime will walk the navigation stack backwards until it finds a UIViewController that implements the function I selected as my Unwind Segue Action (prepareForUnwind) and it will transition to that view controller.


This is the first part of my series on Unwind Segues:

Conversation
  • David says:

    Excellent post. Thank you!

  • Tomme says:

    This is the best post about “unwind segue” I ever see. Very clear, and explain a lot why this functionality seam weird on the first time.

    Thank you for sharing !

  • trianna says:

    What do you do if you want a custom segue transition for the unwind?

  • art says:

    Thanks for the great writing !!

  • Paul says:

    View controller A or view controller B segues to view controller C. The back button on the navigation bar should handle unwinding to view controller A or B, but what if you replace it with a Cancel Bar Button and an unwind segue? The unwind segue would specify the target, either A or B.

  • Umang Bista says:

    Thank you!

    • Umang Bista says:

      How to specify unwind segue, like if I have 4 views , A, B, C and D. In D, there are two buttons. one unwinds to C and another to A?

      • Mike Woelmer Mike Woelmer says:

        Umang, Add a function in your view controller for A with a different name than the one in C. Then you will see two unwind segue functions in the drop down menu. However to go from D to C all you need to do is a pop. You don’t need an unwind segue to go one level backwards.

  • obi says:

    Arguably the best simple explanation of “Unwind segue” ever seen after exhausting searchings.

  • Joseph Ruth says:

    Very nicely done. Have to agree that this was the best post on the subject. I suggest getting this into stack overflow if you can so more can benefit. I’d think they’d let you add a link into an answer somewhere.

  • Frans says:

    Excellent tutorial, thanks – very clearly explained, which helped in my app development! Just had a question regarding unwinding from D to C ( assuming a navigation sequence A-> B-> C-> D ): is there not a danger of creating a brand new version of C each time we transition back from D without an “unwind” ( so that if this is done again and again it would eat up memory)?

    • Mike Woelmer Mike Woelmer says:

      When you navigate in iOS using a navigation controller, it keeps a stack of view controllers that you visited in order. When you unwind, it will pop those view controllers off the stack (reclaiming the memory) until you reach your destination. The destination view controller is not re-created because it was on the stack but the view associated with that view controller was likely unloaded, so it will reload the view.

  • Ivan says:

    Thank you!

  • Will says:

    Thank you so much! Very helpful!

  • Stefano says:

    This is great Mike. Thankfully we have people like you willing to invest their time in simple and clear examples to make fragmented explanations of certain topics crystal clear.
    One note I may add is that, in my understanding, Unwinding Segues are crucial in memory management in cases when CustomSegues are used to navigate back in the stack, as they will keep previous/detail View Controllers in memory unless a specific unwind is called.

    • Mike Woelmer Mike Woelmer says:

      Good point Stefano. Although iOS does a pretty good job of cleaning up the views of view controllers that are in the navigation stack, the view controllers themselves are held onto unless you unwind.

  • Tobias says:

    I tried your tutorial, but the problem now is that I used the animation “cross dissolve” and VC 2 pops up for a second which is pretty ugly. Every segue is a modal segue and every VC is just a normal UIViewController. How can that happen?

  • Chase Walden says:

    OMG. Thank you immensely!!!

    As someone who hasn’t done iOS since 2011, I had no idea how to get storyboards to go back after a segue. I’ve been doing it all programmatically and I still could never get my interfaces to work just right!

    I still am not a huge fan of Storyboards but this makes my hatred towards it a little less.

    Cheers

    • Mike Woelmer Mike Woelmer says:

      Glad you found it useful Chase. It was definitely an aha! moment the first time I figured it out.

  • vilmoskörte says:

    To make this work in Xcode 7, I had to have a

    -(IBAction)prepareForUnwind:(UIStoryboardSegue *)segue;

    also in the header file.

  • Ilhami Yanmaz says:

    Thank you

  • YangJun says:

    Thanks for these tutorials, Mike!! Now I had one question about unwind segue:
    If I have three view controllers(A, B, C), navigation controller’s root view controller is A. A -> B is Show(Push). B -> C is present modally.My unwind action is in A. When I unwind to A, I get the error, “Unbalanced calls to begin/end appearance transitions” in the console. Have you ever meet this situation? I search for the result on the stackover. Someone said it’s a bug. But I wonder what do you think about this.
    http://stackoverflow.com/questions/32042206/unwind-segue-from-modal-popover-resulting-in-unbalanced-calls-to-begin-end-appea

  • anon says:

    Thanks! Simple and it works for iOS 9, thanks

  • Amit Singh says:

    The clearest description of unwind segue anywhere on the Internet!

  • Michael says:

    how would you unwind from C to A.
    But using the UIAlertAction button

    • Mike Woelmer Mike Woelmer says:

      Hi Michael,

      You can give your unwind segue an identifier in interface builder after you create it. Then you can trigger the unwind programmatically when you click on the alert button. You do this the same way you would perform a segue going forward. See my blog post on How to Perform an Unwind Segue Programmatically

  • Pratama says:

    Hi, great article!

    Just wondering how to create unwind segue from back button that navigation controller providing, is it posible to do that?

    Thank you.

    • Mike Woelmer Mike Woelmer says:

      Hi Pratama,

      By default, iOS will add a back button to the navigation bar that will automatically go back one level in the navigation stack. If you need to override this behavior and use an unwind segue to go back more than one, then you need to add your own back button to the navigation bar. You can then ctrl-drag from you back bar button item to the “exit” outlet and specify which unwind segue to perform.

  • I just heard about unwind segues today but all the examples dealt with only A->B and back to A.

    I needed A->B->C->A and so this post was perfect. Just what I needed! Thanks for the clarity and brevity.

  • kj says:

    great tutorial. It helps me. Thanks

  • Comments are closed.