UIActivity activityViewController 在 iPad 上以模态方式呈现,而不是在弹出窗口中
Posted
技术标签:
【中文标题】UIActivity activityViewController 在 iPad 上以模态方式呈现,而不是在弹出窗口中【英文标题】:UIActivity activityViewController being presented modally on iPad instead of in popover 【发布时间】:2012-11-17 18:56:16 【问题描述】:在 ios 6 中使用客户 UIActivity 子类时,可以指定一个自定义视图控制器,当您从初始 UIActionViewController 的视图中选择您的操作时将显示该控制器。为此,您可以从 UIActivity 子类的 activityViewController
方法返回对自定义视图控制器的引用。
根据UIActivity class reference:
activityViewController
此方法的默认实现返回
nil
。使用视图控制器提供额外 UI 的子类可以覆盖此方法以返回该视图控制器。如果此方法返回一个有效对象,系统会为您呈现返回的视图控制器,而不是调用performActivity
方法。在 iPad 上,您的视图控制器显示在弹出框内。在 iPhone 和 iPod touch 上,您的视图控制器以模态方式呈现。您的自定义视图控制器应该为您的自定义 UI 提供一个视图,并且应该处理这些视图中的任何用户交互。完成活动后,不要自行关闭视图控制器。相反,调用
activityDidFinish:
方法并让系统为您关闭它。
请注意第一段末尾的那一点:在 iPad 上,您的视图控制器显示在弹出框内。在 iPhone 和 iPod touch 上,您的视图控制器以模态方式呈现。
但是,在 iPad 上,activityViewController
返回的视图控制器总是以模态显示,无论我如何呈现 UIActivityViewController(模态或通过弹出框)。通过弹出框呈现时,它会导致它崩溃,因为它认为它没有被关闭。
我做错了什么?这是 iOS 6 中的错误吗?
更新:这是一个说明问题的简单 Xcode 项目。随意克隆它,看看你是否能看出我们哪里出错了:github.com/simonwhitaker/GSActivityDemo
【问题讨论】:
这里有同样的问题。我已经修改了原始帖子以添加一个明确的问题,希望你不介意@Gujamin。 太宽泛了,不具体.... :(我可以开始疯狂的猜测,但我宁愿你编辑问题,也许显示一些代码之类的!-哦,你在使用弧吗?跨度> 这似乎与这个 openradar.appspot.com/12034514 相同,这似乎是由这个 SO 用户提交的(也基于 twitter 句柄)...***.com/users/743524/riley-testut 也许值得给他们发消息。 你解决过这个问题吗?我完全无法让自定义 UIActivity 实现activityViewController
在 iPad 上正常工作。 iPhone 上没问题。
对于它的价值,这似乎是最简单的解决方案,但仍然有点奇怪:gist.github.com/mluton/3990658
【参考方案1】:
正如我们所说的 UIActivityViewController,它是向用户显示可用活动的视图。苹果声明如下...
您的应用负责配置、呈现和关闭此视图控制器。视图控制器的配置包括指定视图控制器应该操作的数据对象。 (您还可以指定您的应用程序支持的自定义服务的列表。)在呈现视图控制器时,您必须使用当前设备的适当方式来执行此操作。在 iPad 上,您必须在弹出窗口中显示视图控制器。在 iPhone 和 iPod touch 上,您必须以模态方式呈现。
我把最后一行作为你必须处理视图呈现方式的标志,所以我检查代码是否在 iPad 上运行并相应地使用 UIPopover。正如您可以在这里看到的那样...https://github.com/bufferapp/buffer-uiactivity/blob/master/BufferUIActivity/Views/FirstViewController.m 在以下方法中。
-(IBAction)openUIActivityView:(id)sender
NSString *text = @"Hello world";
NSString *url = @"http://bufferapp.com";
NSArray *activityItems = @[text, url];
BufferUIActivity *bufferActivity = [[BufferUIActivity alloc] init];
UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:@[ bufferActivity ]];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
[self presentViewController:activityView animated:YES completion:^
];
else
// Change Rect to position Popover
self.popup = [[UIPopoverController alloc] initWithContentViewController:activityView];
[self.popup presentPopoverFromRect:CGRectMake(self.view.frame.size.width/2, self.view.frame.size.width/2, 100, 100) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
【讨论】:
嗨,安迪。不,这不是我们要讨论的——我已经澄清了这个问题。我们正在讨论用户选择操作后显示的自定义视图控制器。举一个具体的例子,我正在向我的应用程序添加一个“上传到 Dropbox”操作。所以有一个自定义 UIActivity 子类,它向活动表添加了一个 Dropbox 按钮。当您点击该按钮时,我会显示一个自定义 VC,允许您为文件选择目标文件夹。 VC 应该在 iPad 上的弹出窗口中显示,但始终以模态方式显示。 抱歉,这很奇怪,因为我为 Buffer 所做的 UIActivity 也以模态方式显示在 iPad 上,但 Apple 的 Twitter/Facebook 表格也是如此。我倾向于说这是 iOS6 的问题或文档有误。【参考方案2】:我认为活动视图控制器未在弹出窗口中显示的问题是一个错误,文档反映了正确的意图。但是,我不知道有什么方法可以解决这个 atm。
然而,关于关闭视图控制器的部分是一个不同的问题。您不应该关闭从 -[UIActivity activityViewController]
返回的视图控制器,但您有负责关闭您呈现的弹出框,这反过来也会从层次结构中删除您的自定义视图控制器. (因为它是这样工作的,我倾向于相信自定义视图控制器通常必须显示在弹出窗口中。)
这是一个来自your example app 的代码示例:
UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:activityItems
applicationActivities:applicationActivities];
vc.completionHandler = ^(NSString *activityType, BOOL completed)
[self.activityPopoverController dismissPopoverAnimated:YES];
;
【讨论】:
再想一想,就像 AndyDev 提到的那样,除了打印对话框,所有其他内置活动也以模式屏幕显示。另一个线索是,在呈现自定义视图控制器之前,它会收到-[UIViewController setModalTransitionStyle:]
消息,表明它确实有意以模态方式呈现它。
很好地解决了视图控制器未关闭的问题。谢谢!
我猜可能有一个私有 API 调用,Apple 忽略了公开,它控制是否以模态方式呈现 activityViewController 或在现有的弹出窗口中。【参考方案3】:
我在 iOS 7 中遇到了同样的问题。在弹出窗口中显示自定义视图的解决方案是在 -(void)performActivity
方法中创建并显示它,而不是在 -(UIViewController *)activityViewController
中返回它。
您可以在此链接下的我的问题/答案中查看示例代码:iOS 7 custom UIActivity as popover
【讨论】:
【参考方案4】:我刚刚遇到了同样的问题,但通过将 ViewController 设置为:
[yourViewController setModalPresentationStyle:UIModalPresentationPageSheet];
在
- (UIViewController *)activityViewController
希望对你有帮助
【讨论】:
问题是它应该出现在 iPad 上的弹出窗口中。这不会发生,尤其是如果您通过将演示文稿样式设置为页面表来强制它。以上是关于UIActivity activityViewController 在 iPad 上以模态方式呈现,而不是在弹出窗口中的主要内容,如果未能解决你的问题,请参考以下文章