3

我正在尝试追踪我为使用 MFMailComposeViewController 实例在应用程序中创建电子邮件而编写的 cordova/phonegap 插件中的错误来源。

第一次展示作曲家视图时,每个人都可以正常工作。用户可以通过发送消息或取消来关闭邮件编写器。但是,presentViewController再次调用会使作曲家中的取消和发送按钮变得无用。didFinishWithResult当使用控制器的第二个视图按下无法操作的按钮时,我的代表永远不会调用。

下面是我所看到的简化再现(简单的故事板有一个视图,其中包含一个连接到 my 的 UIButton (IBAction)sendMail)。我在这里的 obj-c 做错了什么?我不应该能够显示控制器,将其关闭并再次显示吗?

视图控制器.h:

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

@interface ViewController : UIViewController


@end

视图控制器.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
4

3 回答 3

8

您遇到的行为的原因是 MFMailComposeViewController 在被解雇时取消了它的委托(可能在 -viewDidDisappear 中:)。

- (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 打印到控制台

Apple 的 MFMailComposeViewController 类参考或类标头中均未记录此委托 nil'ing 行为。可能值得提交一份错误报告,要求澄清和更好的文档。因为它没有记录,所以在未来的版本中行为可能会改变。出于这个原因,根据需要创建和销毁 VC 的建议似乎是很好的常识。

于 2013-08-10T19:57:20.463 回答
1

这以前咬过我一次。这是由于作曲家在被解雇后被解除分配造成的。为了解决这个问题,我会将作曲家的创作放在 viewDidAppear: 中,或者按照 Fahim 的建议放在 sendMail 中。

此外,您可能需要考虑将这两行包装在[MFMailComposeViewController canSendMail];

于 2013-08-10T19:34:11.197 回答
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

这是和我一起工作...

于 2013-08-10T19:31:23.307 回答