Hey there, intrepid iOS developers.
And welcome to this quick tip episode of Route 85.
So check this out.
What you're looking at here is a little app
that I wrote that lets me configure this secret robot
army I've been building.
It's a side project.
Don't tell my manager.
Now, you can see by the storyboard
here that it goes several layers deep
as I select my robot's personality,
mode of transportation, and weaponry.
And then we get to the end, and, well,
I've got to back up a bunch of times in my navigation
controller to get back to my main menu.
It's kind of awkward.
So there are a few ways we could address this.
One way is by using code.
When I finally select my weapon in the last screen,
I could add in a little code like this,
and everything would work.
I jump back to the main menu.
But not always.
In a simple example like this, sure.
I know exactly what order my view controllers will be in.
But that won't always be the case.
What do I do in a situation like this,
where I want to jump to this controller here?
Well, sometimes, it'll be at index 1,
and, other times, it'll be at index 2.
So now my code would have to search through the stack
until I can find the one I want and then pop to that one.
It's an awful lot of code just to jump back
to a view controller.
Isn't it?
Yeah.
Not to mention that now, by using code,
I've introduced some inconsistency
in our navigation logic, right?
Some of our navigation follows segues that
are built into our storyboard.
But some of it now relies purely on code
that has no corresponding entry in Interface Builder.
If another developer were working on our project,
they'd have to start looking around
in, like, all of our files to see what additional navigation
logic we've added instead of being able to rely
on one consistent system.
And we're engineers.
We like consistency.
So the other option is to keep using segues.
Now, you might initially think of doing something like this,
adding a segue that goes from our final view controller
back to our first one.
But that would be a bad thing.
See, by doing so, I wouldn't actually
be jumping back to the first view controller.
My iOS app would create a new main menu view
controller to put on top of my navigation stack.
And I would end up with a giant pile
of view controllers like this.
Yeah, that's not really what I want.
So a better solution here is to create an unwind segue.
This is a segue you define in your storyboard.
And it basically does what it sounds like.
It tells your navigation controller
to unwind through all of its view controllers
until it gets back to the target view controller
that you have specified.
Now, creating an unwind segue is similar to creating
a normal segue, except that instead of Control-Dragging
to the target view controller, you
Control-Drag to your view controller's exit object.
It's this little icon here in your storyboard
that you've probably been ignoring.
For example, let's say I want to make this Cancel button go back
to my main menu.
To do so, I'll just drag from my Cancel button
to this little Exit icon here in my outline, and, let's
try that again.
Oh.
Oh yeah.
That's right.
OK, so this is the thing that confused me with unwind segues.
To use one, you first have to go to your target view controller,
the one you're going to unwind to,
and add a blank ID action method.
In this example, I'll create a method
called unwind to main menu in my main menu view controller.
And you'll notice that I'm passing
in a UI storyboard segue as an argument.
Now you have to do this, or else Interface Builder
won't know that this is a destination
for your unwind segues.
It also comes in handy later, as you'll soon see.
So once I have that in my view controller,
I can go back to Interface Builder,
Control-Drag from my button to this Exit icon
here in my view controller, select the method I just
created-- here it is-- and, voila,
I've created an unwind segue.
Now, when I click this Cancel button in my app,
it will jump back to the view controller that contains this
unwind to main menu method.
And I don't have to worry about where in the hierarchy
it's located, which is nice.
And now I can use it just like any other segue.
So let's revisit our original problem.
To go back to the main menu from my last view controller here,
I can Control-Drag from that view controller
to my exit point to create the segue.
Then I'll give it an identifier, like I
would with any other segue.
And then I can call perform segue with identifier
to get back to the main menu.
Let's see it all in action.
OK, here it goes.
Going, going, oh, much better.
It gets me the logic I wanted.
And I'm insulated from major storyboard changes.
And I get to keep all my navigation
logic nice and consistent.
Oh, and, as an added bonus, if I need this first view
controller to grab any information from that last one,
I have a chance to do that in my unwind to main menu method.
It's kind of the opposite of a traditional prepare
for segue method.
In this case, I can query the previous view controller--
this last one here-- before it's disappeared
from the navigation stack, which can be very useful sometimes.
So this quick tip was shared with me
by our very own Gus Class.
He writes a number of our sample mobile applications,
both on iOS and Android, that you can
find in our GitHub repository.
He also dj'd at Burning Man with a laser light
show that he built himself, which
is way cooler than anything I've ever done in my entire life
ever.
So you win, Gus.
But what about you?
Do have a quick tip?
Do you wear clothing?
Well, then have I got a deal for you?
Send me a quick tip, and if we publish it on the air,
I will send you a T-shirt.
What a bargain!
And as for the rest of you who, I don't know,
I guess don't wear clothes, I'll still
see you soon on "Route 85."