Reputation: 911
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:@"[email protected]"]];
[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:@"[email protected]"]];
[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.
Upvotes: 3
Views: 4110
Reputation: 51
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
}
Upvotes: 0
Reputation: 51
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];
Upvotes: 2
Reputation: 2389
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
Upvotes: 3
Reputation: 4105
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
Upvotes: 1