Home:ALL Converter>Dismissing modal view controller in another modal view controller

Dismissing modal view controller in another modal view controller

Ask Time:2014-07-09T14:34:02         Author:deltacrux

Json Formatter

My iPad app presents a modal view controller from which the user can choose to send an email. My issue is that this opens a new modal view controller (MFMailComposeViewController), which I then can't seem to dismiss properly. This SO thread describes a similar issue, but none of the suggestions in that thread worked for me.

My initial view controller brings up the modal VC using a storyboard segue:

[self performSegueWithIdentifier:@"mySegue" sender:self];

The modal view controller calls the following method when a UIButton is pressed to bring up the iOS default mail composer VC:

- (IBAction)sendWithMail
{
    MFMailComposeViewController *composeMail = [[MFMailComposeViewController alloc] init];

    composeMail.mailComposeDelegate = self.presentingController;

    [self presentViewController:composeMail animated:YES completion:NULL];
}

Here, self.presentingController is a reference to the initial view controller, which conforms to the <MFMailComposeViewControllerDelegate> protocol. When the user has finished writing the email, the delegate method in my initial VC is called. Now I need to close the mail composer view controller and/or my own modal view controller, depending on the result. So I wrote a method in the initial VC like this:

- (void)mailComposeController:(MFMailComposeViewController *)controller
          didFinishWithResult:(MFMailComposeResult)result
                        error:(NSError *)error
{

    [controller dismissViewControllerAnimated:YES completion:NULL];

    switch (result)
    {
        case MFMailComposeResultCancelled:
        {
            break;
        }
        case MFMailComposeResultSaved:
        {
            [self updateStatusMessage:@"Mail saved."];
            break;
        }
        case MFMailComposeResultSent:
        {
            [self updateStatusMessage:@"Mail sent."];
            [self dismissViewControllerAnimated:YES completion:^{}];
            break;
        }
        case MFMailComposeResultFailed:
        {
            [self updateStatusMessage:@"Mail failed."];
            break;
        }
        default:
        {
            break;
        }
    }
}

The idea is that the mail composer should always close, but the modal view controller should close only if the mail was sent successfully. But this doesn't work: when the mail is sent, the app crashes. The only log output is (lldb) and Xcode highlights the return line of main.m in green with Thread 1: EXC_BAD_ACCESS (code=1, address=...).

If I don't try to close the mail composer, and just call [self dismissViewControllerAnimated:YES completion:^{}]; regardless of the result, then both the composer and my modal view controller close and there is no problem. But this is not the behaviour I want.

I've also tried self.presentingViewController instead of just self in the dismiss calls, but that doesn't help.

I feel like I'm missing something fundamental about how view controllers interact, but I can't figure it out. Any help is appreciated!

iOS 7 + Xcode 5

Author:deltacrux,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/24646828/dismissing-modal-view-controller-in-another-modal-view-controller
VRAwesome :

Just implement MFMailComposeViewController delegate method this way.\n\n - (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error\n{\n switch (result)\n {\n case MFMailComposeResultCancelled:\n NSLog(@\"Mail cancelled: you cancelled the operation and no email message was queued.\");\n break;\n case MFMailComposeResultSaved:\n NSLog(@\"Mail saved: you saved the email message in the drafts folder.\");\n break;\n case MFMailComposeResultSent:\n NSLog(@\"Mail send: the email message is queued in the outbox. It is ready to send.\");\n break;\n case MFMailComposeResultFailed:\n NSLog(@\"Mail failed: the email message was not saved or queued, possibly due to an error.\");\n break;\n default:\n NSLog(@\"Mail not sent.\");\n break;\n }\n [[controller presentingViewController] dismissViewControllerAnimated:YES completion:^{\n\n if (result == MFMailComposeResultSent)\n {\n [self dismissViewControllerAnimated:YES completion:nil];\n }\n }];\n\n\n}",
2014-07-09T07:17:34
yy