虽然目前看来 mailto: 设置电子邮件主题和正文的解决方案不起作用,但如果您想将电子邮件正文设置为包含 HTML 并仍然使用 Apple 的系统电子邮件图标,这无论如何都不够通过 UIActivityViewController。
这正是我们想要做的:使用系统图标,但让电子邮件包含 HTML 正文和自定义主题。
我们的解决方案有点像 hack,但它运行良好,至少目前是这样。它确实涉及使用 MFMailComposeViewController,但它仍然允许您将系统邮件图标与 UIActivityViewController 一起使用。
第 1 步:创建一个符合 UIActivityItemSource 的包装类,如下所示:
@interface ActivityItemSource : NSObject <UIActivityItemSource>
@property (nonatomic, strong) id object;
- (id) initWithObject:(id) objectToUse;
@end
@implementation ActivityItemSource
- (id) initWithObject:(id) objectToUse
{
self = [super init];
if (self) {
self.object = objectToUse;
}
return self;
}
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
return self.object;
}
- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
return self.object;
}
第 2 步:继承 UIActivityViewController 并将其变成 MFMailComposeViewControllerDelegate,如下所示:
@interface ActivityViewController : UIActivityViewController <MFMailComposeViewControllerDelegate>
@property (nonatomic, strong) id object;
- (id) initWithObject:(id) objectToUse;
@end
@implementation ActivityViewController
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
switch (result)
{
case MFMailComposeResultSent:
case MFMailComposeResultSaved:
//successfully composed an email
break;
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultFailed:
break;
}
//dismiss the compose view and then the action view
[self dismissViewControllerAnimated:YES completion:^() {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}];
}
- (id) initWithObject:(id) objectToUse
{
self = [super initWithActivityItems:[NSArray arrayWithObjects:[[ActivityItemSource alloc] initWithObject:objectToUse], nil] applicationActivities:nil];
if (self) {
self.excludedActivityTypes = [NSArray arrayWithObjects: UIActivityTypePostToWeibo, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, nil];
self.object = objectToUse;
}
return self;
}
注意:当您打电话时,super initWithActivityItems
您正在包装您将在自定义 ActivityItemSource 中共享的对象
第 3 步:当用户点击邮件图标时,启动您自己的 MFMailComposeViewController 而不是系统控制器。
您可以activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
在 ActivityItemSource 类的方法中执行此操作:
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
if([activityType isEqualToString:UIActivityTypeMail]) {
//TODO: fix; this is a hack; but we have to wait till apple fixes the inability to set subject and html body of email when using UIActivityViewController
[self setEmailContent:activityViewController];
return nil;
}
return self.object;
}
- (void) setEmailContent:(UIActivityViewController *)activityViewController
{
MFMailComposeViewController *mailController = [ShareViewController mailComposeControllerWithObject: self.object withDelegate: activityViewController];
[activityViewController presentViewController:mailController animated:YES completion:nil];
}
在该mailComposeControllerWithObject
方法中,您实例化 MFMailComposeViewController 类的实例并将其设置为包含您想要的任何数据。另请注意,您会将 设置activityViewController
为撰写视图的委托。
这样做的原因是,当显示一个撰写模式时,它会阻止显示其他模式,即您显示自己的撰写视图会阻止显示系统撰写视图。绝对是一个 hack,但它可以完成工作。
希望这可以帮助。