这是做最简单的事情之一,我知道了。 但我一直敲我的头这天。 我已经做了很多次,在过去,但由于某种原因试图提出一个模态视图控制器只是崩溃的应用程序黑屏。 没有报道在控制台或任何东西。 我希望有人可能有这个问题,有一些建议。
此代码是从UIViewController类名为:
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:@"test subject"];
[controller setMessageBody:@"this is the message body" isHTML:NO];
[self presentModalViewController:controller animated:YES];
安德鲁在他的评论中所指出的那样,你检查
+[MFMailComposeViewController canSendMail]
之前,试图把视图控制器? 该行为MFMailComposeViewController
没有明确定义,如果该方法返回NO(也可能在模拟器上运行的时候是这样的,虽然我不知道)。 从文档:
使用这个类之前,你必须经常检查,看看当前的设备被配置为发送电子邮件在所有使用canSendMail方法。 如果用户的设备没有设置电子邮件的传递,您可以通知用户或者干脆禁用应用程序中的电子邮件发送功能。 你不应该试图如果canSendMail方法返回NO使用这个接口。
你有没有试图把另一个视图控制器呢? 这是否崩溃您的应用程序,也?
你想显示显示MFMailComposeViewController之前另一个模式视图控制器? 我有同样的问题,并找到解决方法:
- (void)peopleMultiPickerNavigationController:(PeopleMultiPickerNavigationController *)peoplePicker
didSelectContacts:(NSArray *)contacts {
[self dismissModalViewControllerAnimated:YES];
// some more code here
[self performSelector:@selector(sendEmail) withObject:nil afterDelay:0.45]; // this works only if delay > ~0.4!
// [self sendEmail]; // this won't work
// some more code here
}
- (void) sendEmail {
Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
if (mailClass != nil) {
// We must always check whether the current device is configured for sending emails
if ([mailClass canSendMail]) {
[self displayComposerSheet:emails];
} else {
[self launchMailAppOnDevice:emails];
}
} else {
[self launchMailAppOnDevice:emails];
}
}
我知道这是一个丑陋的解决办法,但我没有发现任何更好:(
我不知道如何相关,这是的,但我一直有想从另一个模式视图控制器返回到我的主视图控制器后呈现MFMailComposeViewController可怕的问题。 这是做不到的。 我试图启动邮件控制器之前关闭此模式的其他视图控制器,发现我的解决方案是不调用:
[self dismissModalViewControllerAnimated:YES];
但改为调用:
[self dismissModalViewControllerAnimated:NO];
然后继续前进,目前的邮件视图控制器。
这一个变化在我的情况就完全不同。 我怀疑这是连接的问题sgosha是有。 刚关掉动画,而不是投入延迟(这可能只是等到动画已经完成)。 貌似在框架给我的错误。
我也许应该进一步解释。 我有我的主视图控制器,其模态弹出一个表视图,允许用户选择他们想要分享一个分享按钮。 从这里,如果让他们在电子邮件挖掘,他们得到一个UIActionSheet让他们进一步决定哪些文件他们希望连接到他们的电子邮件。
有可能在混合的UIActionSheet是造成这个问题的。 模态视图控制器的实际解雇正在采取委托方式回到我的主视图控制器的地方,它是试图解雇模态表视图控制器后启动邮件视图控制器在主视图控制器。
是! 我做到了! 我不能相信,但我解决了这个问题! 这涉及到:
打开一个MFMailComposeViewController从(以上)模态的一些其他打开模态控制器
不幸的是,我不得不承认,再次在昂贵样一个恶魔- iPhones5的时候,苹果仍然forses开发者使用的时候,越野车和不方便代码和组件! 那伟大的例子是MFMailComposeViewController。
但是,现在让我们来看看更惬意的事情。
我们有什么:
- 这个问题表现为在iPhone与iOS 5.1模拟器上与iOS 6。
- 核心问题是,当你试图打开电子邮件控制器从另一个模式控制器模式之一 。
- [MFMailComposeViewController canSendMail] 绝对没有影响我-它没有在这两个方面的工作(这是有或没有可用的电子邮件功能崩溃)。
- [自dismissModalViewControllerAnimated:NO / YES] 并没有改变一般的意义 -这是在崩溃两种方式,但有一点不同的行为。
- 我试图用与mailComposeDelegate的标准方法(如“.mailComposeDelegate =自我”)。
- 我打电话的电子邮件从始发控制器:普通(第一级)控制器以及从模态(第二级)在一个相同的应用程序。
- 应用程序并不总是崩溃- 有时控制器只是不能解雇自己 (按钮“取消”和“发送”成交活跃,但没有动作处理)。 Dependenly的条件(谁是父打开控制器,是动画或不出现等)。
- 也有是否添加或没有任何电子邮件受助没有区别。
那么,什么发现我杀了5个小时,似乎委托是“释放”莫名其妙somewhen。 我想,如果你是作为模式在其他一些模态控制器打开电子邮件控制器,即(先前模式)控制器是由垃圾收集器或其他方式和途径委托进行清洁和清洗(我不希望杀了详细的挖几个小时,所以我会留给苹果的良心)。
不管怎样,在两个词,我的解决办法
与“强”引用某处举行的委托对象。
在我的情况下,该委托的所有者是主视图控制器类(它总是在我的情况下可用的,因为大部分应用程序逻辑的与它的工作)。 这可以是AppDelegate的情况下也。
它看起来像:
@interface SharingTools : NSObject <MFMailComposeViewControllerDelegate>
@property UIViewController* currentParentController;
...
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
if (error)
{
...
}
else
{
// I pass it somewhere before calling the email controller dialog opener method,
// because it's different in case we open the email sender
// from first-level controller or second- (the modal one)
[currentParentController dismissViewControllerAnimated:YES completion:^{
if (_onResult) {
((void(^)(bool))_onResult)(result == MFMailComposeResultSent);
}
}];
}
// and of course clearing all the references etc here
currentParentController.mailComposeDelegate = nil;
currentParentController = nil;
}
-(void)sendEmail //... params here
// (possibly, including to store also currentParentController)
{
currentParentController = ... ;
[currentParentController presentViewController:
newlyCreatedEmailController animated:YES completion:nil];
}
@end
@interface MyMainViewController : UIViewController
@property SharingTools* sharing; // initialize somewhere (on viewDidLoad, for instance)
...
-(void)showSettings
{
...
[self presentModalViewController:settingsController animated:YES];
}
@end
@interface SettingsViewController : UIViewController
...
-(void)sendEmailSupport
{
// again, this is up to you where and how to have either reference
// to main controller (or any other owner of the delegate object)
// or sharing directly
[myMainViewControllerInstance.sharing sendEmail: ... parentController:self];
}
@end
坦白说,代码是那种凌乱,但是这仅仅是一般的想法。 我希望,你会管理自己的更好。
祝你好运,愿上帝保佑微软! ^^