为什么我的MFMailComposeViewController实例只关闭一次?

时间:2013-08-10 19:20:48

标签: ios objective-c

我正在尝试追踪我使用MFMailComposeViewController实例在app中创建电子邮件的cordova / phonegap插件中的错误来源。

第一次呈现作曲家视图时,每个人都可以正常工作。用户可以通过发送消息或取消来解除邮件编辑器。但是,再次调用presentViewController会使作曲家中的“取消”和“发送”按钮变得无用。当使用控制器的第二个视图按下不可操作的按钮时,didFinishWithResult的代理人永远不会打电话。

以下是我所看到的简化版本(简单的故事板有一个包含连接到我的(IBAction)sendMail的单个UIButton的视图)。我在obj-c做错了什么?我不应该能够显示控制器,解除它并再次显示它吗?

ViewController.h:

#import <UIKit/UIKit.h>
#import <MessageUI/MessageUI.h>

@interface ViewController : UIViewController


@end

ViewController.m:

#import "ViewController.h"

@interface ViewController () <MFMailComposeViewControllerDelegate>

@property (nonatomic, weak) IBOutlet UIButton *mailButton;
@property(nonatomic, strong) MFMailComposeViewController* picker;

@end


@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.picker = [[MFMailComposeViewController alloc] init];
    self.picker.mailComposeDelegate = self;
}

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    [self dismissViewControllerAnimated:YES completion:NULL];
}

- (IBAction)sendMail
{
    [self presentViewController:self.picker animated:YES completion:NULL];
}

@end

3 个答案:

答案 0 :(得分:8)

您遇到的行为的原因是MFMailComposeViewController在被解雇时(可能在-viewDidDisappear :)中将其委托给nils。

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.picker = [[MFMailComposeViewController alloc] init];
    self.picker.mailComposeDelegate = self;
}

- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
    // Put a break point here **#breakpoint1**
    [self dismissViewControllerAnimated:YES completion:NULL];
}

- (IBAction)sendMail
{
    // Put a break point here **#breakpoint2**
    [self presentViewController:self.picker animated:YES completion:NULL];
}

在上面的代码注释中显示断点,运行,并在我们单步执行代码时关注我。

  1. 点击调用IBAction的界面按钮;执行暂停在#breakpoint2
  2. 在控制台中输入po self.picker
  3. 您将看到邮件撰写VC实例已分配
  4. 在控制台中输入po self然后po self.picker.delegate
  5. 您会看到这些都打印相同的对象(视图控制器的实例)
  6. 继续运行,点击邮件撰写视图上的关闭按钮;执行暂停在#breakpoint1
  7. 如果需要,请在控制台中检查本地和实例变量,然后继续运行
  8. 点击调用IBAction的界面按钮(这是第二次);执行暂停在#breakpoint2
  9. 在控制台中po self.picker.delegate
  10. nil打印到控制台
  11. Apple的MFMailComposeViewController类引用或类头中没有记录此委托nil'ing行为。它可能值得提交一份错误报告,要求澄清和更好的文档。因为它没有记录,所以在将来的版本中行为可能会改变。出于这个原因,根据需要创建和销毁VC的建议看起来似乎是很好的常识。

答案 1 :(得分:1)

这一点我以前。它是由作曲家在被解雇后被解除分配造成的。为了解决这个问题,我将把作曲家的创作放在viewDidAppear:中,或者像Fahim建议的那样放在sendMail中。

此外,您可能需要考虑在[MFMailComposeViewController canSendMail];

中包装这两行

答案 2 :(得分:0)

我会说下面的行发送邮件......它会起作用。

self.picker = [[MFMailComposeViewController alloc] init];
self.picker.mailComposeDelegate = self;

您将拥有以下内容。

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (IBAction)sendMail
{
    self.picker = [[MFMailComposeViewController alloc] init];
    self.picker.mailComposeDelegate = self;
    [self presentViewController:self.picker animated:YES completion:NULL];
}

@end

这与我合作......