自定义 UIActivity 的主题

Posted

技术标签:

【中文标题】自定义 UIActivity 的主题【英文标题】:Subject for custom UIActivity 【发布时间】:2014-09-11 07:15:54 【问题描述】:

如何指定自定义UIActivity 支持主题?

UIActivityItemSource 协议的文档提到,如果您希望来源提供主题,您可以实现可选的 activityViewController:subjectForActivityType: 选择器:

发布项目时,服务可能会提供单独的主题字段和数据字段,例如电子邮件。如果您希望为支持主题字段的服务提供主题字段,请实施此方法。

但是,据我所知,在任何地方都没有记录我如何实际指定我的自定义 UIActivity 支持主题。这是怎么做到的?

编辑:让我的问题更清楚

假设我有一个自定义活动项源,例如实现UIActivityItemSource 协议的DocumentActivityItemSource,并且我有一个自定义UIActivity,我们可以将其称为SendWithFooMessageActivity

然后我启动一个 UIActivtyViewController:

NSArray *activityItems = @[[[DocumentActivityItemSource alloc] initWithDocument: document]];
NSArray *applicationActivities = @[[[SendWithFooMessageActivity alloc] init]];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems
                                                                                     applicationActivities:applicationActivities];
[parentViewController presentViewController:activityViewController
                                   animated:YES
                                 completion:nil];

现在,在弹出窗口中,我选择SendWithFooMessageActivity。然后活动控制器将在DocumentActivityItemSource 实例上调用activityViewController:itemForActivityType: 以获取一个项目,然后通过调用该对象prepareWithActivityItems: 方法将其转发到SendWithFooMessageActivity

活动项通常是图像、字符串或 url。在这种情况下,假设DocumentActivityItemSource 返回一个字符串,其中包含有关文档的现有简介。然后SendWithFooMessageActivity 可以将此文本用作其 foo 邮件消息的正文。

但是,Foo 消息还要求主题有效。有趣的是,UIActivityItemSource 协议还包含可选的activityViewController:subjectForActivityType:,事实上它被记录为提供支持的服务的主题。

对于 Apple 提供的电子邮件活动,这确实发生了 - 在 DocumentActivityItemSource 上调用 activityViewController:subjectForActivityType:,结果在电子邮件中用作主题。

但是,似乎没有一种方法可以指定我的自定义 SendWithFooMessageActivity 也想从活动项中获取主题?文档提到“支持 [a subject] 的服务”会发生这种情况 - 那么我如何指定我的服务确实支持一个。

此外,activityViewController:thumbnailImageForActivityType:suggestedSize: 也是如此,它应该为“支持的服务”提供缩略图。这适用于默认的 ShareOnTwitter 和 ShareOnFacebook 活动,但似乎没有办法让自定义活动支持它。这可能吗?

到目前为止,我已经使用了@chriszumberge 在下面提供的解决方法,即将activityViewController 短路,并使用itemsource 所需的信息直接初始化自定义活动:

[SendWithFooMessageActivity alloc] initWithSubject: document.title];

但这似乎不是应该使用整个 UIActivityViewController 设置的方式。

【问题讨论】:

【参考方案1】:

我会推荐:

UIActivityViewController *activityVC = [[UIActivityViewController alloc] 
    initWithActivityItems:@[@"Info you're emailing out."] applicationActivities:nil];
[activityVC setValue:@"Custom Email Subject Here" forKey:@"subject"];

但是,由于您使用的是自定义 UIActivity 并且似乎使用的是电子邮件,因此我假设您使用的是 MFMailComposeViewController 发送电子邮件。

在这种情况下,我会在您的自定义UIActivityItemProvider 中为主题字符串创建一个属性,并将其设置为您初始化自定义UIActivity 的任何方法,并将其传递给UIActivityViewController。在提供者中,您可以创建一个字典并为您希望在

中的任何键值设置主题字符串

- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType

方法。

从那里,在您的自定义 UIActivity 中,您可以将主题作为字典中的属性存储在 - (UIViewController*) activityViewController 方法中,并在同一方法中使用下面的代码来初始化电子邮件并设置主题。

MFMailComposeViewController *mailCVC = [[MFMailComposeViewController alloc] init];
mailCVC.mailComposeDelegate = self;
[mailCVC setSubject:theSubject];
[mailCVC setMessageBody:theMessage ishtml:NO];
[mailCVC addAttachmentData:theData mimeType:@"text/csv" fileName:theFileName];

编辑

UIActivityItemProvder 协议定义了 UIActivityViewController 对象使用的方法来检索要操作的数据项(直接来自苹果文档)。 activityViewController:subjectForActivityType: 方法是UIActivityItemSource 协议的一部分。

默认情况下,您的自定义 UIActivityItemProvider 符合 UIActivityItemSource 协议。这就是您需要实现subjectForActivityType: 方法的地方。

然后您可以使用switch/case 语句或一堆if 语句来确定传入的[activityType isEqualToString:@"Custom UIActivity Title"] 是否定义在自定义UIActivity 的activityTitle 方法中。 如果是这样,则返回主题字符串应该是什么。 但这需要在您的自定义 UIActivityItemProvider 子类中。

【讨论】:

这也正是我一直在做的,但它似乎是一个杂项,因为该协议似乎包括对主题和缩略图的支持。我很困惑为什么自定义 UIActivity 无法获得这些 - 似乎是 Apple 的缺陷或疏忽。 @AHM- 我可能误解了您的说法,但自定义 UIActivity 无法使用 activityViewController:subjectForActivityType: 选择器,除非您使自定义 UIActivity 符合UIActivityItemSource protocol. 也许我误会了什么。 UIActivity 会实现UIActivityItemSource 吗?据我了解,您的自定义 UIActivities 应该从基础 UIActivity 继承,并且您的活动项目应该实现 UIActivityItemSource 协议。然后,您将在 UIActivityViewController 上注册项目和自定义活动,然后要求用户选择一个活动,并使用提供的项目配置所选活动。我要问的是如何指定我的自定义UIActivity 想要配置一个主题。 我想说的是你不能(轻易地)在UIActivity 上使用activityViewController:subjectForActivityType:.. 事实上你可能不应该。在评论框中输入太多,请参阅上面的编辑。 是的,我知道——你在编辑中写的就是我上面试图描述的。我也会尝试编辑我的帖子,以使我的问题更清楚。【参考方案2】:

我认为没有一种自动化的方式可以做到这一点。

相反,您只需手动调用源项目上的协议方法来获取主题。您可以在 activityViewController 代码或 -(void)performActivity 方法上执行此操作。

为了安全,你可以先检查一下是否实现:

NSString *subject = nil;
if ([item respondsToSelector:@selector(activityViewController:subjectForActivityType:)]

     subject = [item activityViewController:activityViewController subjectForActivityType:activityType];

【讨论】:

你是如何实现协议的?我认为 UIActivity 通常不会访问原始 UIActivityItemSource。据我了解,UIActivityItemSource 应该从 activityViewController:itemForActivityType: 返回一个项目,并且该项目应该是 NSString、UIImage、UIImage 或其他内容,具体取决于您要共享的内容。您确定可以将 UIActivityItemSource 作为项目返回吗?你能让它在 Apple 为邮件、Twitter 和 Facebook 提供的默认活动中工作吗?

以上是关于自定义 UIActivity 的主题的主要内容,如果未能解决你的问题,请参考以下文章

带有自定义数据的自定义 UIActivity

如何自定义 UIActivityViewController 以仅包含自定义 UIActivity 类型?

自定义 UIActivity :图像图标反转颜色

UIActivity 自定义 activityViewController 在 iPad 上崩溃

自定义 UIActivity:ios8 中提供的未知活动项

iOS 8 自定义 UIActivity 图片黑色背景色