UIActivity activityViewController在iPad上以模式呈现,而不是在popup窗口中呈现

在iOS 6中使用客户UIActivity子类时,可以指定一个自定义的视图控制器,当您从最初的UIActionViewController视图中select动作时,将显示该控制器。 您可以通过从UIActivity子类的activityViewController方法返回对自定义视图控制器的引用来完成此操作。

根据UIActivity类的参考 :

activityViewController

此方法的默认实现返回nil 。 使用视图控制器提供附加UI的子类可以重写此方法以返回该视图控制器。 如果此方法返回一个有效的对象,则系统会为您呈现返回的视图控制器,而不是调用performActivity方法。 在iPad上,您的视图控制器在popup窗口内呈现。 在iPhone和iPod touch上,您的视图控制器以模态方式呈现。

您的自定义视图控制器应该为您的自定义UI提供一个视图,并且应该处理这些视图内的任何用户交互 完成活动后,请勿自行解除视图控制器。 相反,调用activityDidFinish:方法,让系统为你解雇它。

请注意,在第一段结尾处: 在iPad上,视图控制器显示在popup窗口中。 在iPhone和iPod touch上,您的视图控制器以模态方式呈现。

但是,在iPad上,由activityViewController返回的视图控制器总是以模态方式显示,无论我如何呈现UIActivityViewController(无论是通过模式还是通过popup窗口)。 当通过popover展示时,会导致它崩溃,因为它不认为它已被解雇。

我究竟做错了什么? 这是iOS 6中的错误吗?


更新:这是一个简单的Xcode项目,说明了这个问题。 随意克隆它,并玩弄,看看你是否可以看到我们要去哪里错了: github.com/simonwhitaker/GSActivityDemo

正如我们正在讨论的UIActivityViewController,这是显示用户可用活动的视图。 苹果声明如下…

您的应用程序负责configuration,呈现和解散此视图控制器。 视图控制器的configuration涉及指定视图控制器应该在其上操作的数据对象。 (您也可以指定您的应用程序支持的自定义服务列表。)在呈现视图控制器时,您必须使用当前设备的适当方式来执行此操作。 在iPad上,您必须在popup窗口中显示视图控制器。 在iPhone和iPod touch上,您必须以模态forms呈现。

我把最后一行作为一个标志,你必须处理如何呈现视图,所以我检查代码是否在iPad上运行,并相应地使用UIPopover。 正如你可以在这里sere … 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]; } } 

我认为活动视图控制器在popup窗口中不显示的问题是一个错误,文档反映了正确的意图。 但是,我不知道一个办法来解决这个atm。

然而,关于解雇视图控制器的部分是一个不同的问题。 您不应该closures从-[UIActivity activityViewController]返回的视图控制器,但是负责解除您提供的popup窗口,这反过来也将从层次结构中删除您的自定义视图控制器。 (而且因为这样工作,我倾向于相信自定义视图控制器通常必须在popup窗口中显示。)

以下是示例应用中的代码示例 :

 UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities]; vc.completionHandler = ^(NSString *activityType, BOOL completed){ [self.activityPopoverController dismissPopoverAnimated:YES]; }; 

我在iOS 7中遇到了同样的问题。在popup窗口中显示自定义视图的解决scheme是在-(void)performActivity方法中创build并显示它,而不是在-(UIViewController *)activityViewController中返回它。

你可以在我的问题/答案下看到这个链接的例子代码:
iOS 7自定义UIActivity作为popup窗口

我只是有同样的问题,但通过设置ViewController来解决它:

 [yourViewController setModalPresentationStyle:UIModalPresentationPageSheet]; 

 - (UIViewController *)activityViewController 

希望这可以帮助