In the first part of this tutorial, we set up a pair of simple views in Interface Builder that we switched between modally. In this tutorial, we’ll make them somewhat useful and pass data between them using delegates.
The concept of protocols and delegates is an important and somewhat complex one, but I like to think of it in these simplified terms:

Basically, the object that implements our protocol agrees to implement the methods of that protocol. In the case of this tutorial, we’ll be connecting the modal view with our main view using a delegate.
Firstly, we’ll create the interface elements for our project. Open the ModalViewExampleViewController XIB file and create a button and a label as shown.

Next, add those interface elements to ModalViewExampleViewController.h. We’re also adding the necessary IBAction also:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// ModalViewExampleViewController.h @interface ModalViewExampleViewController : UIViewController { UIButton *showDefaultButton, *showFlipButton, *showDissolveButton, *showCurlButton; UIButton *showWithDelegateButton; UILabel *myMessage; } @property (nonatomic, retain) IBOutlet UIButton *showDefaultButton, *showFlipButton, *showDissolveButton, *showCurlButton; @property (nonatomic, retain) IBOutlet UIButton *showWithDelegateButton; @property (nonatomic, retain) IBOutlet UILabel *myMessage; - (IBAction)showDefault:(id)sender; - (IBAction)showFlip:(id)sender; - (IBAction)showDissolve:(id)sender; - (IBAction)showCurl:(id)sender; - (IBAction)showWithDelegate:(id)sender; @end |
Be sure to include the necessary additions to ModalViewExampleViewController.m:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// ModalViewExampleViewController.m #import "ModalViewExampleViewController.h" #import "SampleViewController.h" @implementation ModalViewExampleViewController @synthesize showDefaultButton, showFlipButton, showDissolveButton, showCurlButton; @synthesize showWithDelegateButton, myMessage; ... - (IBAction)showWithDelegate:(id)sender { } ... - (void)dealloc { [showDefaultButton release]; [showFlipButton release]; [showDissolveButton release]; [showCurlButton release]; [showWithDelegateButton release]; [myMessage release]; [super dealloc]; } @end |
Jump to Interface Builder and be sure to link the new elements with the properties we defined. Refer to Part 1 of this tutorial for a guide on how to do that.

The next step is key. We will create a basic protocol and then assign a delegate. Open up ModalViewExampleViewController.h and add this:
|
1 2 3 4 5 6 |
// ModalViewExampleViewController.h @protocol ModalViewDelegate - (void)didReceiveMessage:(NSString *)message; @end |
We then tell ModalViewExampleViewController to implement this protocol:
|
1 2 |
// ModalViewExampleViewController.h @interface ModalViewExampleViewController : UIViewController |
We also need to add the protocol’s method to the main implementation:
|
1 2 3 4 |
// ModalViewExampleViewController.m - (void)didReceiveMessage:(NSString *)message { } |
Once we have these in place, the next step is to set up a reference between the two views. What we will do is define a delegate inside of SampleView so that we can send messages to it.
Include the protocol in ModalViewExampleViewController.h and add the reference:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// SampleViewController.h @protocol ModalViewDelegate; @interface SampleViewController : UIViewController { id delegate; UIButton *dismissViewButton; } @property (nonatomic, assign) id delegate; @property (nonatomic, retain) IBOutlet UIButton *dismissViewButton; - (IBAction)dismissView:(id)sender; @end |
Be sure to synthesize the delegate in SampleViewController.m, and include the necessary header files.
|
1 2 3 4 5 6 7 8 |
#import "SampleViewController.h" #import "ModalViewExampleViewController.h" @implementation SampleViewController @synthesize dismissViewButton; @synthesize delegate; ... |
So far we have defined a protocol inside of our parent view, and defined a delegate in our modal view. The next step is to link them together and make them useful.
Firstly, we’ll write the functions that will handle the messages. Replace the original definition of didReceiveMessage with this:
|
1 2 3 |
- (void)didReceiveMessage:(NSString *)message { [myMessage setText:message]; } |
And also add the following code to showWithDelegate:
|
1 2 3 |
SampleViewController *sampleView = [[[SampleViewController alloc] init] autorelease]; sampleView.delegate = self; [self presentModalViewController:sampleView animated:YES]; |
What we’ve done is create a SampleView object and assigned its delegate to be the parent view. That is, the parent view will be handling messages sent by SampleView.
Open up SampleViewController.m and add the code to send the message.
|
1 2 3 4 5 6 |
// SampleViewController.m - (IBAction)dismissView:(id)sender { [delegate didReceiveMessage:@"Hello World"]; [self dismissModalViewControllerAnimated:YES]; } |
Compile the app and run it. You should be able to see the text “Hello World” passed from one view to another once you dismiss your modal view with delegate. You can extend this any way you like with additional controls on the modal view, such as sliders or text input.
Download the source code for this project here.
I want to give you my congratulations. Your Modal View Controller Examples (part 1 and part 2) are great. I have used them to learn how to do this into my own app. I wish you keep writing this blog for a long time. Thank you so much.
Thanks for this example. It is much clearer than the examples given in the “View Controller Programming Guide for iOS” from Apple. Much appreciated!
The tutorial explains the delegate concept very well. I had read the apple’s documentation on this but was not very clear. Reading this has helped me implement the modal-parent relationship for the view controllers in my app. Thanks for writing such detailed iOS topics. Please keep writing such useful articles. It helps a lot of developers. Thank you !
Thanks for the example. I’m trying to send an array from viewcontroller A to viewcontroller B using your example. I declared the delegate on viewcontroller B and used the following code in viewcontroller A
- (IBAction) graphPressed:(UIButton *)sender {
GraphingViewController *gvc=[[GraphingViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:gvc animated:YES];
[gvc release];
[delegate didReceiveMessage:brain.internalExpression];
}
and the following code in viewcontrollerB
- (IBAction) ViewdidLoad {
CalculatorViewController *cvc =[[CalculatorViewController alloc] init];
cvc.delegate=self;
[cvc release];
}
- (void) didReceiveMessage:(NSMutableArray *)expression {
NSLog(@”message received from CalculatorAppDelegate”);
}
Can’t seem to pass the message. Let me know if you have any comments?
Hi Jack
Although I don’t have your code to check, here are a couple of things to double-check:
- Make sure that the delegate has the proper protocol declaration. Your class for viewcontrollerA should implement a protocol with the definition for didReceiveMessage. This was in my example as
@protocol ModalViewDelegate.- viewcontrollerB needs a member variable that also implements the protocol that viewcontrollerA implements. In my example, I used
id<ModalViewDelegate> delegate;.Generally, if one of these two things aren’t set, you will get compile warnings. Although the app runs, it won’t run as expected and generally won’t tell you why. I suggest treating all errors as warnings, fixing them, then running the app.
If one of the above 2 things aren’t the issue, feel free to send me a message.
Cheers,
Tim
That’s a great example!! Thank you very much!!
Although I’ve got a question. It is possible to send a message from the delegate, to any other controller in your project whatever is the hierarchy? I mean, for example, my app is a tab bar app based. When the app loads, I throw up a modal view, with a button to show another view with a login form. Here, if the log in is OK, I dismiss all the views and I show up the tab bar of the beginning (here the user is logged in). So the thing would be that in the Modal view of the login form, I could send to the tab bar controller the info of the user. Is it possible?
I would appreciate a response :)
Thanks in advance!
Hi Ruben
I never really considered that before. I suppose as long as the delegate has a reference to the controller you want to send messages to, it shouldn’t be a problem.
In the case of your example, I see it as:
[mainWindow] -> [ModalScreen1 > ModalScreen2]
When you create ModalScreen2, it might be better to just pass the mainWindow pointer to ModalScreen2 and do it that way. Keep an eye on memory leaks when you’re debugging.
Also note that this method you’re describing might create unnecessary complexity.
- Tim
Your modal view controllers example is very short, concise and I really appreciate you making this tutorial. Only suggestion I would make is to have your view names match the diagram or be something very obvious like Parent/Child, Mainview/ModalView, or in this case, ObjectA/ObjectB. Still, once I got through the example, I applaud the simplicity of the example.
Pingback: ModalViewControllers |
Pingback: Passing data from navigation view to another view - iPhone Dev SDK Forum
Pingback: Better Way to Pass Data from child to parent in UINavigationController, and modal presentations: reference to parent or delegates? | Technical support, Computer, programming issue, issue tracking, quality assurance
Thank you very much! Both modal view articles were really helpful and have made the concepts completely clear in how they work. Thanks!
A big thank’s for this tuto. It made me understand the concept of protocol and delegate (after more than ten days trying to understand)
Please more tutos like that !
My friend, to put it simply (the same way you write your tutorials…) you and your tutorials rock!! Had a few doubts about delegates until I read your posts! I will recommend this to anyone who wants to start developing with Obj-C. Thanks a lot!
in IOS5, it didn’t like @property (nonatomic, assign) id delegate;
I had to change assign to retain
Hi
thank you for your examples. they are very useful.
I am implementing the examples with ARC enabled.
In your part two I got an error at implementation
– (IBAction)dismissView:(id)sender {
[delegate didReciveMessage:@"Hello world"];
[self dismissModalViewControllerAnimated:YES];
}
it says ‘No known instance methods for selector ‘didReciveMessage’
I have some changes regarding release and autorelease while converting to ARc but how to handle the delegate
thank you
ravi kishore
Awesome tutorial, this has really helped me in making a pause menu for my game!! thanks!!
Pingback: In-App Settings Page - VIP Forum - HOME
Tim,
I can’t thank you enough for these tutorials! They really helped me a lot. Finally something that actually works and you made an excellent job making it easy to understand by beginners like me.
Thanks!
Thanks for the example! Clear and easy!
Pingback: Vistas modales en iOS (iOS Development) | Linkeado
Thank you very much!!!
Excellent tutorial!!!!! I must have looked at about 15 different tutorials over the last 2 weeks trying to figure this out. This made complete sense and was actually dummied down enough for noobs to figure out.
Thanks you so much and keep up the great work. We need more people like you!!!
Best delegate tutorial I’ve seen, and I think I’ve seen them all! Thank you for you this.
Thank you so much for this, it has helped me a lot. Many other sites’ examples are just too confusing, or try to show too much at once. Best regards.
Hi.
I only would like to add that currently it is recommended to dismiss modal view controller not from ModalViewExampleViewController, not from SampleViewController.
This piece of code:
[self dismissModalViewControllerAnimated:YES];
could be added into didReceiveMessage method
or there could be another method added to ModalViewDelegate and implemented inside ModalViewExampleViewController.
Hope I am right and I hope that may help.
Cheers.
Tim, perhaps I’m missing something, but is there any chance there’s something missing, where you state:
“We then tell ModalViewExampleViewController to implement this protocol:
// ModalViewExampleViewController.h
@interface ModalViewExampleViewController : UIViewController”
Don’t you need
…: UIViewController .
I guess this means everyone is just getting it from the download. This actually makes sense. Users—like myself—who have finally gotten far enough with Xcode to try to figure out delegation probably never type or copy from tutorials by that point.
And let me add to the thanks and congratulations, for writing a proper demonstration of the topic. You’ve succeeded by doing three things: stripping out all elements that are not part of the topic, providing a simple diagram, and avoiding the dependent, figurative language that makes Apple’s docs almost useless to the newbie. Nicely done.
But why are there only 20 some posts, all recent, for a 2-year old post?
Followup and explanation: In another comment, I asked about a phrase in angle brackets being missing in your text. When I look at the unmoderated preview of my other comment I see the answer: your blog tool stripped out the phrase ModalViewDelegate in my comment and in your blog! Mystery solved.
Hi Jack
Well, seems like my Social plugin forgot how to display the full date.
As for the original question: I’m not sure what the query is. I originally followed the tutorial line by line to validate it and got a functioning product. Although, this has only been tested with XCode3, so it may be different now.
Cheers, and thanks for the feedback!
- neill
Tim, thank you for the great tutorials! They were really helpful for me.