I'm using MFMailComposeViewController and if I setup the recipients(setToRecipients), I can see 1-2 seconds delay between presenting the controller and the moment the data is loaded (at first an empty controller is presented, then the subject, body and recipients are loaded). It also causes that the navbar appearance settings is reloaded (tintColor).. It is noticeable only on simulator, but on device it happens as well, only it's faster so I can see the reloaded navbar settings.
Code:
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *mailer = [MFMailComposeViewController new];
mailer.mailComposeDelegate = self;
// content
[mailer setSubject:self.mailSubject];
[mailer setMessageBody:self.mailBody isHTML:NO];
[mailer setToRecipients:#[#"asdf#asdf.com"]];
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:mailer animated:YES completion:nil];
});
}
Related
I am using MFMailComposeViewController in my application to compose a feedback E-Mail. The MFMailComposeViewController gets displayed, but can't be closed.
Method used to open the MFMailComposeViewController modal window:
-(IBAction) feedbackBtnClicked:(id)sender {
// Dismiss the Old View Controller
[self dismissViewControllerAnimated:NO completion:NULL];
// Present the New View Controller
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mail = [[MFMailComposeViewController alloc] init];
mail.mailComposeDelegate = self;
[mail setSubject:#"Sample Subject"];
[mail setMessageBody:#"Here is some main text in the email!" isHTML:NO];
[mail setToRecipients:#[#"example#mail.com"]];
[self presentViewController:mail animated:YES completion:NULL];
}
else
{
NSLog(#"This device cannot send email");
}
}
Here is what happens, when clicking on the buttons:
Senden (Send) - The E-Mail gets sent, but the modal window stays open; clicking on that button multiple times results in sending multiple E-Mails without the modal window ever getting closed.
Abbrechen (Cancel) - Nothing happens
How to dismiss make sure the MFMailComposeViewController gets dismissed after clicking on those buttons?
You need to implement the MFMailComposeViewControllerDelegate method mailComposeController:didFinishWithResult:error:, and dismiss the mail view controller…
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result
{
[self dismissViewControllerAnimated:YES completion:NULL];
}
I have a very simple case where a button shows an UIActivityViewController to share some content. The problem is that the mail composer is not dismissed when the user cancel or sends email.
NSArray *items = [NSArray arrayWithObjects:#"share",nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
I tried to dismiss the modal view in the activityViewController.completionHandler but then the console says that another animation is in process and sometimes crash the app, so this isn't the solution. Besides other social networks work well (facebook, twitter) without doing anything.
After some tests I detected that this only occurs if the UIViewController that presents the UIActivityViewController is a child of a UITabBarController.
If in my AppDelegate I create the app like this it doesn't work:
UIViewController > UINavigationController > UITabbarController > Window
but if I remove the tabbar all works fine!:
UIViewController > UINavigationController > Window
A workaround that solves the problem is presenting from the rootviewcontroller.
[self.view.window.rootViewController presentViewController:activityViewController animated:YES completion:NULL];
but I want to know what's happening here.
Thanks! ;)
I had the same issue and after figuring out I get to know that when we don't present mail composer from the class which is currently active on window , it will fail to take responses some time like it will not get even present on every call, same is the problem with dismisal.
It is not that it is only the case with UITabbarController. It can happen to any architecture when you are presenting it from different controller which is not currently on window. That is why your workaround is working and its not wrong though.
I was presenting mail composer from a button tapped inside uipopover. Mail composer was being presented in that popover controller class. And I was facing the same issue you are facing. Then I changed my code to :
MFMailComposeViewController *mailComposer = [MFMailComposeViewController new];
[mailComposer addAttachmentData:data mimeType:#"application/pdf" fileName:model.documentTitle];
[mailComposer setSubject:model.documentTitle]; // Use the document file name for the subject
if(kBccEmailID)
[mailComposer setBccRecipients:[[NSArray alloc]initWithObjects:kBccEmailID, nil ]];
mailComposer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
mailComposer.modalPresentationStyle = UIModalPresentationFormSheet;
AppDelegate *delagate =(AppDelegate *) [[UIApplication sharedApplication]delegate];
mailComposer.mailComposeDelegate = [[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject]; // Set the delegate
[(UIViewController *)[[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject] presentViewController:mailComposer animated:YES completion:nil];
[(UIViewController *)[[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject] is an alternative for your 'self.view.window.rootViewController'.
I have an iPad application, composed of a root view controller that loads a second view controller. Within that second view controller, I have one button that should present an MFMailComposeViewController.
My Problem is:
On the Simulator, this works fine. However, on actual device, pressing this button locks up the screen and seems to disable all user interaction with the interface.
My Code is:
//************** Send Email using Default IM ************************
-(void) showEmailModalView
{
NSLog(#"Start method <ExportStatisticsController> : <showEmailModalView> --");
// emailTextField.text = [emailTextField.text stringByReplacingOccurrencesOfString:#"(null)" withString:#""];
// subjectTextField.text = [subjectTextField.text stringByReplacingOccurrencesOfString:#"(null)" withString:#""];
// messageBodyTextView.text = [messageBodyTextView.text stringByReplacingOccurrencesOfString:#"(null)" withString:#""];
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self; // <- very important step if you want feedbacks on what the
//user did with your email sheet
[picker setSubject:#""];
NSArray *torec=[[NSArray alloc] initWithObjects:#"xyz#company.com", nil];
[picker setToRecipients:torec];
[torec release];
//------ message body ---
NSString *body =#"";
[picker setMessageBody:body isHTML:NO]; // depends. Mostly YES, unless you want to send it as plain text (boring)
picker.navigationBar.barStyle = UIBarStyleBlack; // choose your style, unfortunately, Translucent colors behave quirky.
// picker.ModalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:picker animated:YES];
[picker release];
NSLog(#"End method <ExportStatisticsController> : <showEmailModalView> --");
}
What could I be doing wrong to cause a screen freeze like this?
The device is probably not set up to send mail.
Before using the MFMailComposeViewController you should call [MFMailComposeViewController canSendMail] to ensure that the device is configured to send mail.
It's probably a good idea too to check that your picker variable is non-nil before trying to present it as a modal view controller.
Has anyone been successful showing the standard Apple MFMailComposeViewController from a UIModalPresentationStyleFormSheet view controller on the iPad?
When I do this the view shows as expected but when the user taps any of the input text views, the subject for example, and the keyboard slides pressing the Cancel button will show the "Delete Draft" & "Save Draft" popover outside of the screen bounds.
If I change the modal view to full screen it works properly.
I don't think you are presenting it as a Form Sheet then. Using this code works wonders for me:
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:#"Subject"];
[mailViewController setMessageBody:#"" isHTML:NO];
mailViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:mailViewController animated:YES];
I have the following block of code which works fine in the simulator and on most devices, on some devices however (all on the same iOS version 4.2.1) the app is crashing when it gets to the [mailComposer release] call, does anyone have any insight on why this would be happening?
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
mailComposer.mailComposeDelegate = self;
[mailComposer setSubject:[self.webView stringByEvaluatingJavaScriptFromString:#"document.title"]];
[mailComposer setMessageBody:[NSString stringWithFormat:#"Hello, \n\n Here is the link we discussed. \n %#", [self.webView.request URL]] isHTML:NO];
[self presentModalViewController:mailComposer animated:YES];
[mailComposer release];
I had this exact same problem and I really have NO idea why it would crash, because presentModalViewController is supposed to retain the view controller. After fighting with it, I finally just added a property on my view controller which retained the reference to the mfMailComposeViewController and it worked fine. :/
MFMailComposeViewController* mfMailComposeViewController;
#property (nonatomic, retain) MFMailComposeViewController *mfMailComposeViewController;
then..
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:subject];
[controller setBody:body];
self.mfMailComposeViewController = controller;
[controller release];
Ok so I managed to figure out what was causing my issue with the help of my new iPad 2.
The issue was caused by not having any mail accounts configured, simply adding
if ([MFMailComposeViewController canSendMail])
before I create and present the view prevents the crashing, in my else block I added an UIAlertView to let the user know they cannot access that feature without first configuring a mail account.