iOS: How To Pass Data with an Unwind Segue

Yesterday, I got really excited after reading this great tutorial on how to unwind a segue. I knew there was a way to unwind a segue, but I never quite got how to use it, so I just used the standard dismissViewController code to go back to the initial view controller instead.

However, the part that excited me most about this was not just doing a standard segue unwind, but the realization of how to pass information back to the original view controller using the unwind segue!

Consider this simple application:

When I select a color from the ColorsViewConroller, the color gets passed back to the main view controller, where it is set as the main view controller’s background color. To do this simple task in the past, I would use either the delegate, block, or notification pattern.

Here is how to accomplish this same task using the unwind segue:

The Setup

I created a very simple application:

iOS-Storyboard

The NTRMainViewController has a button “Change Color” with triggers a segue to bring up the NTRColorsTableViewConroller using the modal animation. The NTRColorsTableViewConroller is configured with a “colorCell”, which just changes a background color. The NTRColorsTableViewController’s initial table view configuration is as follows:

@interface NTRColorsTableViewController ()

@property (strong, nonatomic) NSArray *colors;

@end

@implementation NTRColorsTableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.colors count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"colorCell"; forIndexPath:indexPath];

    cell.contentView.backgroundColor = self.colors[indexPath.row];
    
    return cell;
}


#pragma mark - Setter / Getter Overrides

- (NSArray *)colors
{
    if (!_colors) {
        self.colors = @[[UIColor blueColor],
                        [UIColor lightGrayColor],
                        [UIColor cyanColor],
                        [UIColor yellowColor],
                        [UIColor magentaColor],
                        [UIColor purpleColor],
                        [UIColor brownColor],
                        [UIColor redColor],
                        [UIColor grayColor],
                        [UIColor whiteColor],
                        [UIColor orangeColor]];
    }
    return _colors;
}

@end

Create an Unwind Action

The key with the unwind segue is that you need to create the unwind action in the view controller you want to unwind to! In my case, I want to unwind from the NTRColorsTableViewController to the NTRMainViewConroller. So I need to create the unwind action in the NTRMainViewConroller:

// NTRMainViewConroller.m
- (IBAction)unwindFromModalViewController:(UIStoryboardSegue *)segue
{

}

Connect to the Unwind Action

And just like with other IBActions, we need to connect to it in the storyboard. I’m going to start by triggering the unwind from the NTRColorsTableViewConroller’s Cancel button. Here’s how:

  • Control drag the cancel button to the Exit sign
  • Select the previously specified unwind action (see above section)
  • Add an identifier to the unwind segue
  •  

    Trigger the Segue

    The unwind segue now acts as any other segue! It will automatically be triggered when the Cancel button is clicked in the NTRColorsTableViewController. However, you also want to trigger it in the tableView:didSelectRowAtIndexPath method, when the user selects a color cell:

    //NTRColorsTableViewController.m
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        self.selectedColor = self.colors[indexPath.row];
        [self performSegueWithIdentifier:@"colorSelected" sender:self];
    }
    

    Pass the Data!

    Finally, you are ready to pass the color from the NTRColorsTableViewController to the NTRMainViewConroller! There are two ways to do this:

    Unwind Action

    Remember, the unwind action passes in a the segue, so you now have access to the source view controller – which is the color view controller in our case. You can now fill in your unwind action with the necessary code:

    //NTRMainViewConroller.m
    - (IBAction)unwindFromModalViewController:(UIStoryboardSegue *)segue
    {
        if ([segue.sourceViewController isKindOfClass:[NTRColorsTableViewController class]]) {
            NTRColorsTableViewController *colorsViewConroller = segue.sourceViewController;
            // if the user clicked Cancel, we don't want to change the color
            if (colorsViewConroller.selectedColor) {
                self.view.backgroundColor = colorsViewConroller.selectedColor;
            }
        }
    }
    

    Prepare for Segue

    Again, the unwind segue is still a segue. So just like any other segue, you can take advantage of the prepareForSegue:sender method in your view controller.

    //NTRMainViewConroller.h
    @interface NTRMainViewController : UIViewController
    
    @property (strong, nonatomic) UIColor *backgroundColor;
    
    @end
    
    //NTRMainViewConroller.m
    
    // other methods
    
    #pragma mark - Setter Overrides
    
    - (void)setBackgroundColor:(UIColor *)backgroundColor
    {
        _backgroundColor = backgroundColor;
        self.view.backgroundColor = backgroundColor;
    }
    
    
    //NTRColorsTableViewConroller.m
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([segue.destinationViewController isKindOfClass:[NTRMainViewController class]]) {
            NTRMainViewController *mainViewConroller = segue.destinationViewController;
            if (self.selectedColor) {
                mainViewConroller.backgroundColor = self.selectedColor;
            }
        }
    }
    

    You can view the full example source code on Github. Happy Unwinding!

    Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.