Question

I have a some kind of action sheet UIView which calls MFMailComposeViewController after tapping a button in it, the MFMailComposeViewController gets called and presented successfully, but it doesn't dismiss when the I tap Cancel and sometimes crashes, I know this is a known problem, but I have tried all the known fixes but it doesn't work for me. That's my code:

SendFeedback.h:

#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>

@interface SendFeedback : UIView <UITableViewDelegate, UITableViewDataSource, MFMailComposeViewControllerDelegate, UINavigationControllerDelegate>

//Useless code to the problem.    

@property (nonatomic, retain) MFMailComposeViewController *feedBackComposer;

@end

SendFeedback.m:

- (void)baseInit
{
    //Useless code to the problem. 

    feedBackComposer = [[MFMailComposeViewController alloc] init];
    [feedBackComposer setMailComposeDelegate:self];
    [feedBackComposer setToRecipients:[NSArray arrayWithObject:@"info@getibox.com"]];
    [feedBackComposer setMessageBody:@"" isHTML:NO];
    [feedBackComposer setSubject:@"What I Love About iBox"];
}

And to call the composer: - (void)sendFeedbackComposer { [self.window.rootViewController presentViewController:feedBackComposer animated:YES completion:nil]; }

To dismiss it:

- (void)mailComposeController:(MFMailComposeViewController *)feedBackComposer didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    //This method doesn't get called.

    [self.window.rootViewController dismissViewControllerAnimated:YES completion:nil];

    NSLog(@"Error: %@", error);
}

EDIT: So, all the answers provided in this question were correct, and it was all my bad. What I wanted to do is: I had a UINavigationController which includes a UITableView one of the cells in that view should trigger an action sheet which is a UITableView by adding it as a subview, just like the previous one, this view also includes cells and one of them will do an action and it is calling an MFMailComposeViewController, which gets called but doesn't dismiss successfully even though I had its delegate set up and all the methods correct, the cause of the problem was the way of calling the MFMailComposeController, I first removed from super view that little UITableView then presented the MFMailComposeController, so when I dismissed the mail composer it crashed without even giving a result, which made me confuse the cause of the crash with the delegate method, fool me. Here's the code:

- (void)removeView
{
    if (self) {
        [UIView animateWithDuration:0.3
                         animations:^{backgroundView.alpha = 0;}
                         completion:^(BOOL finished){

        [UIView animateWithDuration:.3
                         animations:^{self.frame = CGRectMake(0, 568, 320, 568);}
                         completion:^(BOOL finished){[self removeFromSuperview];}];
        }];
    }
}
- (void)sendFeedbackComposer
{
    feedBackComposer = [[MFMailComposeViewController alloc] init];
    [feedBackComposer setMailComposeDelegate:self];
    [feedBackComposer setToRecipients:[NSArray arrayWithObject:@"info@getibox.com"]];
    [feedBackComposer setMessageBody:@"" isHTML:NO];
    [feedBackComposer setSubject:@"What I Love About iBox"];

    [self.window.rootViewController presentViewController:self.feedBackComposer animated:YES completion:nil];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (indexPath.row) {
        case 2: //That's the index of the MailComposer caller.
            [self removeView];
            [self sendFeedbackComposer];
            break;
        case 6:
            [self removeView];
            break;
        default:
            break;
    }
}
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    [feedBackComposer.presentingViewController dismissViewControllerAnimated:YES completion:nil];

    NSLog(@"Error: %@", error);
}

Thanks to Stefan Atanasov, Jim, and Vitaly S.

Was it helpful?

Solution 2

To add something to Vitaly S.'s answer (due to lack of reputation I can't comment directly on it, sorry) - the delegate method is called, so the problem is the dismissal. You can try this:

[feedBackComposer.presentingViewController dismissViewControllerAnimated: YES completion: nil];

OTHER TIPS

Are you sure that delegate method isn't called? I made a test and it's called, but to dismiss mail composer use such code:

[feedBackComposer dismissViewControllerAnimated: YES completion: nil];

Also it's really strange to implement delegates in view implementation, not in view controller

The delegate methods need to be called from the viewController, not from within the UIView.

Your view controller that calls the UIView will have your delegates

<UITableViewDelegate, UITableViewDataSource, MFMailComposeViewControllerDelegate, UINavigationControllerDelegate>

within it's header file.

You need to make a delegate method to pass information from the UIView to the controller, which will in turn call the mail and table delegate methods.

Here is a link to a question that demonstrates how to use a delegate protocol to trigger a method in the view controller from the UIView.

Trigger a method in UIViewController from its View

Hope this helps, Jim

you need to check is it device is configure to send mail by checking MFMailComposeViewController is avail to respond or not.

  if([MFMailComposeViewController canSendMail]){
  //your code
  }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top