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];
}
Related
I am using QLPreviewController for showing the pdf. And I am sending pdf by tapping the share button and then tap on email in the QLPreviewController.
But i don't know how to get that share button method in QLPreviewController to validate that the email account is available or not. Here is the screenshot:
Please let me know about this.
Thanks in advance.
if you have UInavigationController then you can add a bar button for sharing the content. Or you can add a share button in your viewcontroler.
Use MessageUI. Add the delegates MFMessageComposeViewControllerDelegate, MFMailComposeViewControllerDelegate.
- (IBAction)contactBtn:(id)sender {
if ([MFMailComposeViewController canSendMail]){
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
[controller setSubject:#"Subject"];
[controller setMessageBody:#" " isHTML:NO];
[controller setToRecipients:[NSArray arrayWithObjects:#"a#wa.com",nil]];
controller.mailComposeDelegate = self;
[self presentViewController:controller animated:YES completion:NULL];
}
else{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Failed!" message:#"Mail can not be sent. Check your email settings." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil] ;
[alert show];
}
}
- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error {
[self dismissViewControllerAnimated:YES completion:NULL];
}
The QL previewer is working on separate process. Something like a different app. So there is no way to customize the share button. see details here
This may help you. See this answer.
I have a UIAlertView that launches an email and a messages screen. When a user clicks on the Alert's button, both views open, however, they do not close.
I have a tried adding:
-(void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES];
}
to the body of the class, however, it did not help.
Here is how the email is presented:
[viewController presentViewController:email animated:YES completion:nil];
Edit Here is the entire code I am using to present the email:
//send email...
-(void)sendEmail{
//mail composer
Class mailClass = (NSClassFromString(#"MFMailComposeViewController"));
if(mailClass != nil){
if([mailClass canSendMail]){
//get the current view controller from the App Delegate
apptester_appDelegate *appDelegate = (apptester_appDelegate *)[[UIApplication sharedApplication] delegate];
UIViewController *viewController = [appDelegate getViewController];
MFMailComposeViewController *email = [[MFMailComposeViewController alloc] init];
email.mailComposeDelegate = self;
//navigation bar color depends on iOS7 or lower...
if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1){
[[email navigationBar] setTintColor:[UIColor blackColor];
}else{
[[email navigationBar] setBarTintColor:[UIColor blackColor]];
}
//show the model view...
[viewController presentViewController:email animated:YES completion:nil];
}
}
}
Has anyone else experienced this error?
This may not be relevant, but this app has a tab bar.
Make sure you have set delegate for mail controller
mail.mailComposeDelegate = viewController;
Also try this as well,
[viewController.tabBarController presentViewController:email animated:YES completion:nil];
Have you try this method and pass "controller" instead of self:
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[controller dismissViewControllerAnimated:YES completion:nil];
}
Thanks!
It is the responsibility of presenting controller to dismiss the modal view. Make sure you implement the delegate of the modal in the presenting controller.
Two things:
1) Make sure you set the mailComposeDelegate on the MFMailComposeViewController before you present it.
2) In your mailComposeController:didFinishWithResult:error: method, you should do:
[controller dismissModalViewControllerAnimated:YES];
I'm having trouble with removing a modal view.
I want to show (after pressing a button) a my own SendMailViewController which it self shows a MFMailComposeViewController. Then and after pressing cancel of send, in my own SendMailView controller in didFinishWithResult i do a [self dismissModalViewControllerAnimated:YES] and that works. The MFMailComposeView goes away.
But then the screen stays black....it think i also have to remove my SendMailViewController from it's parent. That's where i pushed the button...even after [self removeFromParentViewController] it still stays black...
Where do i go wrong?
And yes i would like the extra viewcontroller (SendMailViewController) because that controller will become the delegate of MFMailComposeViewController. Otherwise my caller (controller with the button) get's to much responsibility. Or do i also go wrong here?
Thanks,
/jr00n
- (IBAction)tapExportButton:(id)sender
{
SendMailViewController *sendMailController = [[SendMailViewController alloc]init];
[self presentViewController:sendMailController animated:YES completion:^() {[sendMailController openMailDialog];}];
[sendMailController release];
}
SendMailViewController:
- (void)openMailDialog
{
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
mailer.mailComposeDelegate = self;
...
[self presentModalViewController:mailer animated:YES];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
....
// Remove the mail view
// first i did this:
// [self dismissModalViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}];
}
The problem is with the [self dismissViewControllerAnimated:YES completion:^{[self removeFromParentViewController];}]; in your didFinishWithResult method.
Remove that line and add the following line,
[controller dismissViewControllerAnimated:YES completion:^{[self dismissViewControllerAnimated:YES completion:nil]}];
That make sure we dismiss the controller after dismissing the MailController
I have a View Controller which displays a table view. The VC calls another VC to display the send SMS view to the user, the code for this SMS VC is:
- (void) sendSMSWithBody: (NSString*) body andRecipients: (NSArray*) recipients
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if ([MFMessageComposeViewController canSendText])
{
controller.messageComposeDelegate = self;
controller.body = body;
controller.recipients = recipients;
[[UIApplication sharedApplication].delegate.window.rootViewController addChildViewController:self];
[self presentModalViewController:controller animated:YES];
}
}
- (void) messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
[self dismissModalViewControllerAnimated:YES];
[[UIApplication sharedApplication].delegate.window.rootViewController removeFromParentViewController];
}
(I know the call to sharedApplication is a bit hacky, but it will suffice for now. the rootViewController is a UINavigationController which has its root controller set to the table view controller)
I am invoking the SMS VC from the table VC like so:
- (void ) viewDidAppear:(BOOL)animated
{
static BOOL presentedSMSVC = NO;
if (!presentedSMSVC)
{
SendSMSController *sendSMS = [[SendSMSController alloc] init];
[sendSMS sendSMSWithBody:#"body"
andRecipients:[NSArray arrayWithObject:#"123456789"]];
presentedRegisterVC = YES;
}
}
The problem is that after the user sends the SMS the table view cells are not displaying.
I thought maybe I need to refresh the view/table so I added a protocol callback from the 2nd VC to the first which gets invoked when the user sends the SMS, and then within the callback call [self.tableView reloadData] But it made no difference.
So I got rid of the intermediary class and edited the table view to display the SMS view directly like this:
- (void ) viewDidAppear:(BOOL)animated
{
static BOOL presentedRegisterVC = NO;
if (!presentedRegisterVC)
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if ([MFMessageComposeViewController canSendText])
{
controller.messageComposeDelegate = self;
controller.body = #"body";
controller.recipients = [NSArray arrayWithObject:#"12345678"];
[self presentModalViewController:controller animated:NO];
}
}
}
- (void) messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
[self dismissModalViewControllerAnimated:NO];
}
But now the MFMessageComposeViewController doesn't dismiss (although messageComposeViewController:didFinishWithResult: does get called)
What is the problem with both approaches? Thanks
For the second variant, I changed to:
[self presentViewController: controller animated: YES completion:nil];
[self dismissViewControllerAnimated:YES completion:nil];
And that worked, haven't tried applying to the first method.
I faced a similar UI issue.
My case was: The controller, let's say controller A, in which I had written the code to present and dismiss the MFMessageComposeController, was not being used directly as the active controller rather I was using A.view as a subview over another controller, say controller B. So writing the following was distorting the view:
[self presentViewController:composeVC animated:YES completion:nil];
But then writing the following solved my issue:
[self.customTabbarNavigation presentViewController:composeVC animated:YES completion:nil];
The customTabbarNavigation, was the controller B, ans was actually the navigation controller which was active when controller A's view was visible.
Same change had to be made for dismissing the composeVC.
I have a view with a few text boxes and labels. I'd like to email the view containing this information to either a contact list or just a text box with an email address in it.
I can't get the view to email. I'd like to send the whole page without having to somehow list every text box. How do I email the view with this code:
[controller setMessageBody:textBoxesAndInfo isHTML:YES];
-(IBAction)sendMail {
// create an instance of MFMailComposeViewController for sending an e-mail
MFMailComposeViewController *controller =
[[MFMailComposeViewController alloc] init];
// set controller's delegate to this object
controller.mailComposeDelegate = self;
[controller setToRecipients:#[#"hello#example.com"]];
[controller setSubject:#"Subject"];
[controller setMessageBody:textBoxesAndInfo isHTML:YES];
// show the MFMailComposeViewController
[self presentModalViewController:controller animated:YES];
}
// called when the user finishes sending an e-mail
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES];
}
Remember to include the MessageUI framework.