虽然目前看来mailto:解决方案无法设置电子邮件主题和正文,但如果您想将电子邮件正文设置为包含HTML并仍然使用Apple的系统电子邮件图标通过UIActivityViewController,这种方法显然是不够的。
这正是我们想要做的:使用系统图标,但电子邮件包含HTML正文和自定义主题。
我们的解决方案有点像黑客方式,但它目前运行良好。 它确实涉及使用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:
break;
case MFMailComposeResultCancelled:
break;
case MFMailComposeResultFailed:
break;
}
[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,而不是系统默认的。
你可以在 ActivityItemSource 类的 activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
方法中实现此功能:
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
if([activityType isEqualToString:UIActivityTypeMail]) {
[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方法,但它能胜任工作。
希望这有所帮助。