UIActivity activityViewController étant présenté de manière modale sur iPad au lieu de dans popover

Lorsque vous utilisez une sous-class UIActivity client dans iOS 6, il est possible de spécifier un controller de vue personnalisé qui sera affiché lorsque votre action est choisie dans la vue initiale de UIActionViewController. Pour ce faire, renvoyez une reference à un controller de vue personnalisé à partir de la méthode activityViewController de votre sous-class UIActivity.

Selon la reference de class UIActivity :

activityViewController

L'implémentation par défaut de cette méthode renvoie nil . Les sous-classs qui fournissent une interface user supplémentaire à l'aide d'un controller de vue peuvent replace cette méthode pour renvoyer ce controller de vue. Si cette méthode renvoie un object valide, le système présente le controller de vue renvoyé pour vous, au lieu d'appeler la méthode performActivity . Sur iPad, votre controller de vue est présenté à l'intérieur d'un popover. Sur iPhone et iPod touch, votre controller de vue est présenté de manière modale.

Votre controller de vue personnalisé doit fournir une vue avec votre interface user personnalisée et gérer les interactions de l'user à l'intérieur de ces vues. Une fois l'activité terminée, ne rejetez pas le controller de vue vous-même. Au lieu de cela, appelez la méthode activityDidFinish: et laissez le système le rejeter pour vous.

Notez ce bit à la fin du premier paragraphe: Sur iPad, votre controller de vue est présenté à l'intérieur d'un popover. Sur iPhone et iPod touch, votre controller de vue est présenté de manière modale.

Cependant, sur iPad le controller de vue returnné par activityViewController affiche toujours modal, peu importe comment je présente le UIActivityViewController (soit modalement ou via un popover). Lors de la présentation via un popover, il provoque un crash car il ne pense pas qu'il a été rejeté.

Qu'est-ce que je fais mal? Est-ce un bug dans iOS 6?


Mise à jour: voici un projet Xcode simple qui illustre le problème. N'hésitez pas à cloner et à jouer pour voir si vous pouvez voir où nous allons mal: github.com/simonwhitaker/GSActivityDemo

Comme nous parlons de UIActivityViewController, qui est la vue montrant les activités disponibles à l'user. Apple déclare ce qui suit …

Votre application est responsable de la configuration, de la présentation et de la suppression de ce controller de vue. La configuration du controller de vue implique la spécification des objects de données sur lesquels le controller de vue doit agir. (Vous pouvez également spécifier la list des services personnalisés pris en charge par votre application.) Lors de la présentation du controller de vue, vous devez le faire en utilisant les moyens appropriés pour le périphérique actuel. Sur iPad, vous devez présenter le controller de vue dans un survol. Sur iPhone et iPod touch, vous devez le présenter de manière modale.

J'ai pris la dernière ligne comme un signe que vous devez gérer comment la vue est présentée, donc je vérifie si le code fonctionne sur iPad et utilise un UIPopover en conséquence. Comme vous pouvez le voir ici … https://github.com/bufferapp/buffer-uiactivity/blob/master/BufferUIActivity/Views/FirstViewController.m dans la méthode suivante.

 -(IBAction)openUIActivityView:(id)sender { NSSsortingng *text = @"Hello world"; NSSsortingng *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]; } } 

Je pense que le problème avec le controller de vue d'activité n'apparaissant pas dans un popover est un bug et les docs reflètent l'intention correcte. Cependant, je ne connais pas de moyen de contourner ce problème.

La partie sur le rejet du controller de vue, cependant, est une question différente. Vous n'êtes pas censé ignorer le controller de vue à partir -[UIActivity activityViewController] vous revenez -[UIActivity activityViewController] , mais vous êtes responsable de l'annulation du survol que vous avez présenté, ce qui à son tour supprimera également votre controller de vue personnalisé de la hiérarchie. (Et parce que cela fonctionne de cette façon, je suis enclin à croire que le controller de vue personnalisé devrait normalement être montré dans le popover.)

Voici un exemple avec le code de votre application exemple :

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

J'ai eu le même problème dans iOS 7. La solution pour montrer la vue personnalisée dans le popover est de le créer et de l'afficher dans la méthode -(void)performActivity au lieu de le returnner dans -(UIViewController *)activityViewController .

Vous pouvez voir un exemple de code dans ma question / réponse sous ce lien:
iOS 7 personnalisé UIActivity comme popover

J'ai juste eu le même problème mais l'ai résolu en réglant le ViewController à:

 [yourViewController setModalPresentationStyle:UIModalPresentationPageSheet]; 

dans

 - (UIViewController *)activityViewController 

J'espère que cela t'aides