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

标签 ios objective-c

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

第一次呈现 Composer View 时,每个人都可以正常工作。用户可以通过发送消息或取消来关闭邮件编辑器。但是,再次调用 presentViewController 会导致 composer 中的 Cancel 和 Send 按钮变得无用。当在 Controller 的第二个 View 中按下无法操作的按钮时,我的 didFinishWithResult 委托(delegate)从不调用。

下面是我所见内容的简化重现(简单的 Storyboard 有一个 View ,其中包含一个连接到我的 (IBAction)sendMail 的 UIButton)。我在 obj-c 中做错了什么?难道我不能显示一个 Controller ,关闭它,然后再次显示它吗?

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

最佳答案

您遇到的行为的原因是 MFMailComposeViewController nils 它在被解雇时是委托(delegate)(可能在 -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. 你会看到它们都打印相同的对象(你的 View Controller 的实例)
  6. 继续运行,然后点击邮件撰写 View 上的关闭按钮;执行在#breakpoint1 处停止
  7. 如果需要,在控制台中检查局部变量和实例变量,然后继续运行
  8. 点击调用您的 IBAction 的界面按钮(这是第二次);执行在#breakpoint2 停止
  9. 在控制台中输入 po self.picker.delegate
  10. nil 打印到控制台

Apple 的 MFMailComposeViewController 类引用或类 header 中均未记录此委托(delegate) nil'ing 行为。提交错误报告以请求澄清和更好的文档可能是值得的。因为它没有记录,所以在未来的版本中行为可能会改变。出于这个原因,根据需要创建和销毁 VC 的建议当然看起来像是很好的常识。

关于ios - 为什么我的 MFMailComposeViewController 实例只关闭一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18165545/

相关文章:

ios - iTunes 如何解析 m3u 文件

objective-c - 使用多个 nsarraycontroller 更改选定对象

objective-c - Objective-C 是否逐行运行代码?

ios - 等待直到收到 NSNotification

objective-c - 如何实现 UIImageView 的对齐网格功能?

ios - 为什么在 xcode 功能中,推送/远程通知有两个选项

objective-c - TableView 中项目数的内存限制

ios - 如何在没有硬核索引的情况下删除父数组中子数组的重复项

ios - 如何为 sprite-kit 游戏创建加载屏幕

ios - 如何在 iOS 上使用 Firebase 取消 Nest ETA?