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];
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 this wired problem with UIActivityViewController on iPad when dismissing it.
What I have is a MainViewController from which I present a view controller like so (modal view):
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
[self presentViewController:self.readerViewController animated:YES completion:nil];
In the ReaderViewController's toolbar I have a UIButton to show UIActivityViewController for PDF sharing.
This is how I present the UIActivityViewController:
_activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[document.fileURL] applicationActivities:nil];
UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:_activityViewController];
[popup presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
When UIActivityViewController is presented it works as expected. It will dismiss if I press anywhere on the screen, also as expected. The problem is if I double tap somewhere on the screen, both the UIActivityViewController and ReaderViewController will be dismissed at the same time.
Now, I want only UIActivityViewController to be dismissed not ReaderViewController.
Any solution for this ?
/Cheers
There is a way, declare UIPopoverController *popup as a global variable or property.
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 am trying to bring up an Email Window in my application, however the top toolbar that is suppose to have Cancel and Send is being obscured by the navigation controller.
I believe the reason is that I am calling
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setToRecipients:[NSArray arrayWithObject:#"internalapps#microstrategy.com"]];
[controller setSubject:#"Mobile HelpDesk App"];
[controller setMessageBody:#"" isHTML:NO];
if (controller){
[self presentViewController:controller animated:YES completion:^{}];
}
}
From a child ViewController that controls a view inside a scrollview (For Paging).
How do I get the toolbar to be on top of the navigation bar? Right now, it's only showing the new email window, but I cannot cancel or send the email.
I tried using [self.parentViewController presentViewController:controller animated:YES completion:^{}];, but that didn't do anything.
Thanks!
You can't use presentViewController:... from a view controller whose view isn't at the top of the view hierarchy (and so most likely doesn't occupy the whole screen). As you've seen, this results in a presented view which is perhaps partially visible and perhaps doesn't respond to touches in some areas.
Trying self.parentViewController is the correct solution (though the code you show is invalid). You need to ensure that you navigate far enough up the hierarchy to get to the 'root' view controller and present from there.
This sounds like it could be as simple as changing:
[self presentViewController:controller animated:YES completion:^{}];
to
[self.navigationController presentViewController:controller animated:YES completion:^{}];
Hope this helps you.
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.