1

I have UIAlertController. On click of OK, presenting MFMailComposeViewController. I dismiss the MFMailComposeViewController by tapping on cancel button in email compose screen. MFMailComposeViewController's delegate methods are called properly while dismissing. MFMailComposeViewController dismisses successfully. Immediately after that if I try the same feature(flow) again. I am not getting alert, rather getting below error. What could be the reason? I tried most of the solution available in stackoverflow. still getting the same issue.

Attempt to present <UIAlertController: 0x13890beb0> on <MFMailComposeViewController: 0x1371ef000> whose view is not in the window hierarchy!**

I am using self presentViewController to present alertcontroller and MFMailComposeViewController.

sample code is here :

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error{
    [controller dismissViewControllerAnimated:YES completion: nil];


}


UIAlertController * alertController=   [UIAlertController alertControllerWithTitle:@"Title" message:@"message"                    preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction* ok = [UIAlertAction
                         actionWithTitle:@"Ok"
                         style:UIAlertActionStyleDefault
                         handler:^(UIAlertAction * action)
                         {
                             [alertController dismissViewControllerAnimated:YES completion:nil];

                             MFMailComposeViewController *mailComposerVC = [MFMailComposeViewController new];

                             mailComposerVC.mailComposeDelegate = self;

                             if ([MFMailComposeViewController canSendMail]) {


                                 [self presentViewController:(MFMailComposeViewController*)mailComposerVC animated: true completion: nil];
                             }

                         }];
    UIAlertAction* cancel = [UIAlertAction
                             actionWithTitle:@"Cancel"
                             style:UIAlertActionStyleDefault
                             handler:^(UIAlertAction * action)
                             {
                                 [alertController dismissViewControllerAnimated:YES completion:nil];

                             }];

    [alertController addAction:ok];
    [alertController addAction:cancel];

    [self presentViewController:alertController animated:false completion:nil];
rmaddy
  • 314,917
  • 42
  • 532
  • 579
user516542
  • 107
  • 2
  • 8

2 Answers2

1

Please use below code to present mail controller :

UIAlertController * alertController=   [UIAlertController alertControllerWithTitle:@"Title" message:@"message"                    preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction* ok = [UIAlertAction  actionWithTitle:@"Ok"  style:UIAlertActionStyleDefault  handler:^(UIAlertAction * action) {
                         [alertController dismissViewControllerAnimated:YES completion:nil];

                         MFMailComposeViewController *composer = [[MFMailComposeViewController alloc] init];

                         mailComposerVC.mailComposeDelegate = self;

                         if ([MFMailComposeViewController canSendMail]) {

                            [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:mailComposerVC
                                                                                             animated:YES
                                                                                           completion:nil];

                         }

                     }];
UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Cancel"  style:UIAlertActionStyleDefault  handler:^(UIAlertAction * action)  {
                             [alertController dismissViewControllerAnimated:YES completion:nil];

                         }];

[alertController addAction:ok];
[alertController addAction:cancel];

[self presentViewController:alertController animated:false completion:nil];
Vinodh
  • 5,262
  • 4
  • 38
  • 68
  • The above lines of code is part of button action. My requirement is, to show alert before showing email composer. – user516542 Oct 26 '16 at 09:21
0

Hard to say what's exactly causing a problem. I've found a few possible reasons, hopefully, fixing one of them will end up as a solution to your problem.

You should call dismissViewControllerAnimated: on the presenting view controller not the presented one. Even though it usually works, in your case it could brake something. You have 3 places where you do it wrong. This is one of them:

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(nullable NSError *)error
{
    [self dismissViewControllerAnimated:YES completion:nil];  // `controller` is replaces with `self`
}

Also you shouldn't present mailComposerVC before alertController is dismissed. You may use the completion block for this.

Do you test on the simulator? MFMailComposeViewController doesn't work properly there. Try to run on a real device, maybe, the crash will magically disappear.

Artem Stepanenko
  • 3,423
  • 6
  • 29
  • 51