iOS 6 and Xcode 4.5 has a new feature referred to as "Unwind Segue":
Unwind segues can allow transitioning to existing instances of scenes in a storyboard
In addition to this brief entry in Xcode 4.5's release notes, UIViewController now seem to have a couple of new methods:
- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender - (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
How do unwind segues work and what they can be used for?
Use segues to define the flow of your app's interface. A segue defines a transition between two view controllers in your app's storyboard file. The starting point of a segue is the button, table row, or gesture recognizer that initiates the segue. The end point of a segue is the view controller you want to display.
An object that prepares for and performs the visual transition between two view controllers.
First, select a segue in your storyboard, then go to the attributes inspector and give it a name such as “showDetail”. Technically the sender parameter is whatever triggered the segue, but you can put whatever you want in there.
An unwind segue (sometimes called exit segue) can be used to navigate back through push, modal or popover segues (as if you popped the navigation item from the navigation bar, closed the popover or dismissed the modally presented view controller). On top of that you can actually unwind through not only one but a series of push/modal/popover segues, e.g. "go back" multiple steps in your navigation hierarchy with a single unwind action.
When you perform an unwind segue, you need to specify an action, which is an action method of the view controller you want to unwind to.
Objective-C:
- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue { }
Swift:
@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) { }
The name of this action method is used when you create the unwind segue in the storyboard. Furthermore, this method is called just before the unwind segue is performed. You can get the source view controller from the passed UIStoryboardSegue
parameter to interact with the view controller that initiated the segue (e.g. to get the property values of a modal view controller). In this respect, the method has a similar function as the prepareForSegue:
method of UIViewController
.
iOS 8 update: Unwind segues also work with iOS 8's adaptive segues, such as Show and Show Detail.
Let us have a storyboard with a navigation controller and three child view controllers:
From Green View Controller you can unwind (navigate back) to Red View Controller. From Blue you can unwind to Green or to Red via Green. To enable unwinding you must add the special action methods to Red and Green, e.g. here is the action method in Red:
Objective-C:
@implementation RedViewController - (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue { } @end
Swift:
@IBAction func unwindToRed(segue: UIStoryboardSegue) { }
After the action method has been added, you can define the unwind segue in the storyboard by control-dragging to the Exit icon. Here we want to unwind to Red from Green when the button is pressed:
You must select the action which is defined in the view controller you want to unwind to:
You can also unwind to Red from Blue (which is "two steps away" in the navigation stack). The key is selecting the correct unwind action.
Before the the unwind segue is performed, the action method is called. In the example I defined an unwind segue to Red from both Green and Blue. We can access the source of the unwind in the action method via the UIStoryboardSegue parameter:
Objective-C:
- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue { UIViewController* sourceViewController = unwindSegue.sourceViewController; if ([sourceViewController isKindOfClass:[BlueViewController class]]) { NSLog(@"Coming from BLUE!"); } else if ([sourceViewController isKindOfClass:[GreenViewController class]]) { NSLog(@"Coming from GREEN!"); } }
Swift:
@IBAction func unwindToRed(unwindSegue: UIStoryboardSegue) { if let blueViewController = unwindSegue.sourceViewController as? BlueViewController { println("Coming from BLUE") } else if let redViewController = unwindSegue.sourceViewController as? RedViewController { println("Coming from RED") } }
Unwinding also works through a combination of push/modal segues. E.g. if I added another Yellow view controller with a modal segue, we could unwind from Yellow all the way back to Red in a single step:
When you define an unwind segue by control-dragging something to the Exit symbol of a view controller, a new segue appears in the Document Outline:
Selecting the segue and going to the Attributes Inspector reveals the "Identifier" property. Use this to give a unique identifier to your segue:
After this, the unwind segue can be performed from code just like any other segue:
Objective-C:
[self performSegueWithIdentifier:@"UnwindToRedSegueID" sender:self];
Swift:
performSegueWithIdentifier("UnwindToRedSegueID", sender: self)
As far as how to use unwind segues in StoryBoard...
Step 1)
Go to the code for the view controller that you wish to unwind to and add this:
Objective-C
- (IBAction)unwindToViewControllerNameHere:(UIStoryboardSegue *)segue { //nothing goes here }
Be sure to also declare this method in your .h file in Obj-C
Swift
@IBAction func unwindToViewControllerNameHere(segue: UIStoryboardSegue) { //nothing goes here }
Step 2)
In storyboard, go to the view that you want to unwind from and simply drag a segue from your button or whatever up to the little orange "EXIT" icon at the top right of your source view.
There should now be an option to connect to "- unwindToViewControllerNameHere"
That's it, your segue will unwind when your button is tapped.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With