我使用的是新UIActivityViewController
类iOS6的为用户提供各种共享选项的用户。 你可以传递参数给它,如文本,链接和图像数组并没有休息。
如何定义收件人? 例如通过邮件或短信分享应该能够接受的接受者,而是我无法弄清楚如何调用该行为。
我不希望有需要使用MFMessageComposeViewController
和UIActivityViewController
分别为刚刚击败共享控制器的目的。
有什么建议?
UIActivityViewController类参考
编辑:这现在已经提交苹果公司,随后与重复的bug报告合并。
在OpenRadar bug报告
Answer 1:
这里一切归功于艾曼纽尔,因为他想出了大部分的代码。
虽然我想我会发布他的代码修改后的版本是帮助设置到收件人。
我用MFMailComposeViewController类别
#import "MFMailComposeViewController+Recipient.h"
#import <objc/message.h>
@implementation MFMailComposeViewController (Recipient)
+ (void)load {
MethodSwizzle(self, @selector(setMessageBody:isHTML:), @selector(setMessageBodySwizzled:isHTML:));
}
static void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL)
{
Method origMethod = class_getInstanceMethod(c, origSEL);
Method overrideMethod = class_getInstanceMethod(c, overrideSEL);
if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
} else {
method_exchangeImplementations(origMethod, overrideMethod);
}
}
- (void)setMessageBodySwizzled:(NSString*)body isHTML:(BOOL)isHTML
{
if (isHTML == YES) {
NSRange range = [body rangeOfString:@"<torecipients>.*</torecipients>" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];
if (range.location != NSNotFound) {
NSScanner *scanner = [NSScanner scannerWithString:body];
[scanner setScanLocation:range.location+14];
NSString *recipientsString = [NSString string];
if ([scanner scanUpToString:@"</torecipients>" intoString:&recipientsString] == YES) {
NSArray * recipients = [recipientsString componentsSeparatedByString:@";"];
[self setToRecipients:recipients];
}
body = [body stringByReplacingCharactersInRange:range withString:@""];
}
}
[self setMessageBodySwizzled:body isHTML:isHTML];
}
@end
Answer 2:
对于添加对象到iOS6的使用UIActivityViewController的电子邮件,这是任何人都可以使用。所有你需要做的就是调用下面在初始化UIActivityViewController的最佳解决方案。
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities];
[activityViewController setValue:@"My Subject Text" forKey:@"subject"];
而你UIActivityViewController填充了一个主题。
Answer 3:
我只是想出了一个解决这个问题(在我的情况设置电子邮件的主题):作为内部的UIActivityViewController将调用在某些时候setMessageBody:isHTML:方法MFMailComposeViewController类的,只是截取该呼叫和内部进行打电话到SETSUBJECT:方法。 感谢“方法混写”美特殊,它看起来像:
#import <objc/message.h>
static void MethodSwizzle(Class c, SEL origSEL, SEL overrideSEL)
{
Method origMethod = class_getInstanceMethod(c, origSEL);
Method overrideMethod = class_getInstanceMethod(c, overrideSEL);
if (class_addMethod(c, origSEL, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(c, overrideSEL, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
} else {
method_exchangeImplementations(origMethod, overrideMethod);
}
}
@implementation MFMailComposeViewController (force_subject)
- (void)setMessageBodySwizzled:(NSString*)body isHTML:(BOOL)isHTML
{
if (isHTML == YES) {
NSRange range = [body rangeOfString:@"<title>.*</title>" options:NSRegularExpressionSearch|NSCaseInsensitiveSearch];
if (range.location != NSNotFound) {
NSScanner *scanner = [NSScanner scannerWithString:body];
[scanner setScanLocation:range.location+7];
NSString *subject = [NSString string];
if ([scanner scanUpToString:@"</title>" intoString:&subject] == YES) {
[self setSubject:subject];
}
}
}
[self setMessageBodySwizzled:body isHTML:isHTML];
}
@end
使用UIActivityViewController之前调用下面的代码行:
MethodSwizzle([MFMailComposeViewController class], @selector(setMessageBody:isHTML:), @selector(setMessageBodySwizzled:isHTML:));
然后传递给UIActivityViewController定制UIActivityItemProvider对于UIActivityTypeMail返回一个HTML的NSString像:
<html><head>
<title>Subject of the mail</title>
</head><body>
Body of the <b>mail</b>
</body></html>
该电子邮件的主题是从HTML标题中提取(使用纯文本的那部分,没有HTML实体或标签)。
使用这种方法,我让你阐述一种优雅的方式来设置邮件收件人。
Answer 4:
虽然它出现,目前的mailto:设置邮件主题和正文不工作,这在任何情况下是不够的,如果你想设置电子邮件正文中包含HTML,仍然使用苹果的系统邮件图标的解决方案通过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:
//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
为撰写视图的委托。
这部作品的原因是显示撰写模式时,它可以防止显示的其他情态动词,即你展示自己撰写视图块被所示的系统撰写视图。 这绝对是一个黑客,但它能够完成任务。
希望这可以帮助。
Answer 5:
你应该能够包括使用NSURL对象和邮寄地址收件人:方案(或短信:文本消息)。
从UIActivity类的引用:
UIActivityTypeMail对象的帖子所提供的内容,新的电子邮件。 当使用该服务,您可以提供的NSString和UIImage的对象和NSURL对象指向本地文件作为活动项目的数据。 你也可以指定NSURL对象,其内容使用mailto模式。
因此,这样的事情应该工作:
NSString *text = @"My mail text";
NSURL *recipients = [NSURL URLWithString:@"mailto:foo@bar.com"];
NSArray *activityItems = @[text, recipients];
UIActivityViewController *activityController =
[[UIActivityViewController alloc]
initWithActivityItems:activityItems
applicationActivities:nil];
[self presentViewController:activityController
animated:YES completion:nil];
Answer 6:
我不知道有关收件人,但它好像在iOS的7,以后你可以通过符合设定的电子邮件的主题UIActivityItemSource
协议和实施方法activityViewController:subjectForActivityType:
文章来源: How do I set recipients for UIActivityViewController in iOS 6?