I have two view controllers, firstViewController and secondViewController. I am using this code to switch to my secondViewController (I am also passing a string to it):
secondViewController *second = [[secondViewController alloc] initWithNibName:nil bundle:nil];
second.myString = @"This text is passed from firstViewController!";
second.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:second animated:YES];
[second release];
I then use this code in secondViewController to switch back to the firstViewController:
[self dismissModalViewControllerAnimated:YES];
All of this works fine. My question is, how would I pass data to the firstViewController? I would like to pass a different string into the firstViewController from the secondViewController.
hmm, look for the notification centre and pass back info in a notification. here is apples take on it - I take this approach personally unless any one has any other suggestions
Define a delegate protocol in the second view controller and make the first one the delegate of the second.
I could be way out of place here, but I am starting to much prefer the block syntax to the very verbose delegate/protocol approach. If you make vc2 from vc1, have a property on vc2 that you can set from vc1 that is a block!
Then, when something happens in vc2 that you want to tell vc1 about, just execute the block that you defined in vc1!
This allows you to send data from vc2 back to vc1. Just like magic. IMO, this is a lot easier/cleaner than protocols. Blocks are awesome and need to be embraced as much as possible.
EDIT - Improved example
Let's say we have a mainVC that we want to present a modalVC on top of temporarily to get some input from a user. In order to present that modalVC from mainVC, we need to alloc/init it inside of mainVC. Pretty basic stuff. Well when we make this modalVC object, we can also set a block property on it that allows us to easily communicate between both vc objects. So let's take the example from above and put the follwing property in the .h file of modalVC:
Then, in our mainVC, after we have alloc/init'd a new modalVC object, you set the block property of modalVC like this:
So we are just setting the block property, and defining what happens when that block is executed.
Finally, in our modalVC, we could have a tableViewController that is backed by a dataSource array of strings. Once a row selection is made, we could do something like this:
And of course, each time we select a row in modalVC, we are going to get a console output from our NSLog line back in mainVC. Hope that helps!
You need to use delegate protocols... Here's how to do it:
Declare a protocol in your secondViewController's header file. It should look like this:
Don't forget to synthesize the myDelegate in your implementation (SecondViewController.m) file:
In your FirstViewController's header file subscribe to the SecondDelegate protocol by doing this:
Now when you instantiate SecondViewController in FirstViewController you should do the following:
Lastly, in the implementation file for your first view controller (FirstViewController.m) implement the SecondDelegate's method for secondViewControllerDismissed:
Now when you're about to dismiss the second view controller you want to invoke the method implemented in the first view controller. This part is simple. All you do is, in your second view controller, add some code before the dismiss code:
Delegate protocols are EXTREMELY, EXTREMELY, EXTREMELY useful. It would do you good to familiarize yourself with them :)
NSNotifications are another way to do this, but as a best practice, I prefer using it when I want to communicate across multiple viewControllers or objects. Here's an answer I posted earlier if you're curious about using NSNotifications: Firing events accross multiple viewcontrollers from a thread in the appdelegate
EDIT:
If you want to pass multiple arguments, the code before dismiss looks like this:
This means that your SecondDelegate method implementation inside your firstViewController will now look like: