Passing Data Between View Controllers (iOS Obj-C)

Torrey Betts / Thursday, May 29, 2014

Introduction

When designing an app that makes use of multiple view controllers it may become necessary to pass data back and forth between the view controllers. This common occurance will be covered in this blog post by demonstrating passing data to the next view controller as well as passing data back to the previous view controller.

Passing Data Forward to a View Controller

Passing Data Forward to a View Controller

To pass data forward to the next view controller, expose properties on the next view controller. In this example, we'll expose a data property of type NSString. In your own project you can use whatever data type you wish, including custom objects.

@interface SecondViewController : UIViewController
@property (nonatomic, retain) NSString *data;
@end

The code to create an instance of this view controller along with passing of the data is as follows. This example passes the text contained in a label to the second view controller.

- (void)passDataForward
{
    SecondViewController *secondViewController = [[SecondViewController alloc] init];
    secondViewController.data = _label.text; // Set the exposed property
    [self.navigationController pushViewController:secondViewController animated:YES];
}

When your next view controller is loading it's then possible to use the assigned data. Our sample project sets the text of a label using the exposed data variable.

UILabel *label = [[UILabel alloc] initWithFrame:CGRectInset(top, 5, 5)];
label.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth|
        UIViewAutoresizingFlexibleBottomMargin;
label.textAlignment = NSTextAlignmentCenter;
label.text = [NSString stringWithFormat:@"Your data: %@", _data]; // Make use of the exposed data property
[self.view addSubview:label];

Passing Data Back to the Previous View Controller

To pass data back to the previous view controller, you will need to create a delegate protocol the second view controller uses and exposes to the previous view controller. The sample delegate shown in this example forces implementation of the dataFromController: method by the adopter. The second view controller exposes the delegate protocol through the delegate property.

@protocol SecondViewControllerDelegate <NSObject>
@required
- (void)dataFromController:(NSString *)data;
@end

@interface SecondViewController : UIViewController
@property (nonatomic, retain) NSString *data;
@property (nonatomic, weak) id<SecondViewControllerDelegate> delegate;
@end

On the first view controller we need to adopt this delegate protocol.

@interface FirstViewController () <SecondViewControllerDelegate>
{
    UILabel *_label;
    UIButton *_button;
}
@end

Now that the delegate protocol is adopted, we must implement the required methods. In this method, our sample sets the label text to the data passed in and disables the button.

- (void)dataFromController:(NSString *)data
{
    _label.text = data;
    _button.enabled = NO;
}

For this method and adoption of the delegate protocol to work, we must set the delegate property to self.

- (void)passDataForward
{
    SecondViewController *secondViewController = [[SecondViewController alloc] init];
    secondViewController.data = _label.text;
    secondViewController.delegate = self; // Set the second view controller's delegate to self
    [self.navigationController pushViewController:secondViewController animated:YES];
}

Download the Example Project

The Xcode project source code for this quick tip can be downloaded by clicking this link.

By Torrey Betts