Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Retreiving data from second screen in push segue

I am using push segue and navigation control. Now when doing some code in second screen, I want to retrieve that data to my parent screen.

How would do retrieve data from the second screen ?? I need to code in swift.

I'll post an answer soon, just give me a minute (:

1 Answer

You should go for delegation. It's not easy at first, but when you get the hang of it, it's really nice to work with.

Say you have two view controllers - ParentViewController and ChildViewController. You want to send data from the ChildViewController to the ParentViewController.

To summarize, this is what we're gonna do:

  1. Declare a protocol in the ChildViewController, as well as declaring a delegate method and a delegate property.
  2. Call the delegate method in ChildViewController.
  3. Make ParentViewController conform to the delegate declared in ChildViewController
  4. Set the delegate property in ParentViewController
  5. Implement the delegate method in ParentViewController

STEP 1 - Declare a protocol in the ChildViewController, as well as declaring a delegate method and a delegate property

// ChildViewController.h

@class ChildViewController;

@protocol ChildViewControllerDelegate <NSObject>
- (void)viewDidLoadInViewController:(ChildViewController *)viewController;
@end

@interface ChildViewController : UIViewController
@property (strong, nonatomic) id <ChildViewControllerDelegate> delegate;
@end

This is av very simple protocol as it only has one method. You have to put the protocol in the ChildViewController, because it's that view controller which will decide when the method will be run (as I like to think about it). You also have to declare a delegate property. You will send the delegate method to this object in the ChildViewController.

STEP 2 - Call the delegate method in ChildViewController

Here you will decide when the delegate method will be sent to the delegate object. I will put it in the viewDidLoad. Of course, you can put it anywhere you want.

// ChildViewController.m

- (void)viewDidLoad
{
    [self.delegate viewDidLoadInViewController:self];
}

It's nice to include the ChildViewController in the delegate method, so that you can access properties (as an example).

STEP 3 - Make ParentViewController conform to the delegate declared in ChildViewController

This is of course done in the ParentViewController like this (remember to import the ChildViewController.h file):

// ChildViewController.m

@interface ParentViewController () <ChildViewControllerDelegate>

You can do this in both the .h and the .m file. Xcode will now tell you that you need to implement certain delegate methods, which we will do in the last step.

STEP 4 - Set the delegate property in ParentViewController

Since we're using a segue, we can set the delegate property there, like this:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{
    if ([segue.identifier isEqualToString:@"segueIdentifier"])
    {
        ChildViewController *childViewController = (ChildViewController *)segue.destinationViewController;
        childViewController.delegate = self;
    }
}

Now the ChildViewController knows which object to send the delegate method to, specifically the ParentViewController.

STEP 5 - Implement the delegate method in ParentViewController

- (void)viewDidLoadInViewController:(ChildViewController *)viewController
{
    NSLog(@"Hello, world");
}

When you run the application and segue to the ChildViewController, ChidViewController will send the delegate method to the delegate object - the ParentViewController - which will write "Hello, world" to the console.

Don't hesitate to ask if there is something you don't understand or something I've done wrong.

I am using Swift. So I need to write code in swift.

Well, the syntax is different, but I guess the pattern is the same (haven't tried Swift, though). You should try on your own with my example and the link I provided.

Can you please explain me the step 4

is it same like: if segue.identifier == "segue identifier" { var childViewcontroller = segue.destinationViewController as! childViewControllerdelegate }

I didn't get that what exactly I have to do in step 4 and 5

In step 4 you're just getting a reference to the ChildViewController by setting it to the destination view controller of the segue and at the same time type casting it. This is just to set the delegate property. The ParentViewController won't get the message if you don't do this. I'm not sure about the syntax in Swift.

In step 5 you're just implementing the delegate method declared in the protocol. You have to make ParentViewController call this method somewhere in code. ChildViewController decides when to run the method and ParentViewController decides what should happen when the method is run.