How to pass an NSString from modal view to parent view

567 views Asked by At

I have a parent view and a modal view with a text box. What I am trying to do is pass whatever is entered into the text box from the modal view and then pass it to a label in the parent view which updates the label to what was entered. I hope that made any sense.

I have been pulling my hair out for a couple of weeks trying to figure this out with no luck. I found many examples and tutorials about segues and passing between views that are being pushed but nothing about modal views and passing back to the parent view.

I have been trying to understand this and need a good example. I kind of understand the prepare for segue concept but for some reason, I just can't figure this one out. Any help on this would be much appreciated and you would be my hero for life lol.

1

There are 1 answers

1
csd On

In my project that uses segues, here's how I did it (note that I'm new to iOS, so there's probably "better" ways, and this may be obvious to the iOS veterans):

The short version: define a callback protocol in your modal view controller's .h file. When your modal view controller closes, it checks to see if the presenter implements that protocol and invokes those methods to pass along the data.

So like you said, let's say your modal view controller just gathers a single string value from the user and then they click OK or Cancel. That class might look like this:

@interface MyModalViewController : UIViewController
...
@end

I'm suggesting you add a protocol like this to the same header:

@protocol MyModalViewControllerCallback
-(void) userCancelledMyModalViewController:(MyModalViewController*)vc;
-(void) userAcceptedMyModalViewController:(MyModalViewController*)vc
                                withInput:(NSString*)s;
@end

Then in MyModalViewController.m, you add a viewDidDisappear with code similar to this:

-(void) viewDidDisappear:(BOOL)animated {
    UIViewController* presenter = self.presentingViewController;
    // If the presenter is a UINavigationController then we assume that we're
    // notifying whichever UIViewController is on the top of the stack.
    if ([presenter isKindOfClass:[UINavigationController class]]) {
        presenter = [(UINavigationController*)presenter topViewController];
    }
    if ([presenter conformsToProtocol:@protocol(MyModalViewControllerCallback)]) {
        // Assumes the presence of an "accepted" ivar that knows whether they
        // accepted or cancelled, and a "data" ivar that has the data that the
        // user entered.
        if (accepted) {
            [presenter userAcceptedMyModalViewController:self withInput:data];
        }
        else {
            [presenter userCancelledMyModalViewController:self];
        }
    }
    [super viewDidDisappear:animated];
}

And finally in the parent view, you implement the new @protocol, e.g. in the .h:

@interface MyParentViewController : UIViewController <MyModalViewControllerCallback>
...
@end

and in the .m:

@implementation MyParentViewController
...
-(void) userCancelledMyModalViewController:(MyModalViewController*)vc {
    // Update the text field with something like "They clicked cancel!"
}
-(void) userAcceptedMyModalViewController:(MyModalViewController*)vc
                                withInput:(NSString*)s {
    // Update the text field with the value in s
}
...
@end