web-dev-qa-db-fra.com

Crash lors de la présentation de UIImagePickerController sous iOS 6.0

Mon application prend uniquement en charge les orientations paysagères via les propriétés supportedInterfaceOrientation.

À l'aide d'un iOS antérieur à iOS 6, mon application peut charger avec succès une instance de UIImagePickerController via presentViewController:animated:completion: même si le UIImagePickerController lui-même ne prend en charge que l'orientation portrait.

Le sélecteur d'images s'est simplement présenté latéralement à l'utilisateur. L'utilisateur a fait pivoter le téléphone, a choisi son image, puis est revenu au paysage.

Sous iOS 6.0, l'appel de presentViewController:animated:completion: avec l'instance UIImagePickerController plante l'application. Je peux empêcher le plantage en ajoutant des options de portrait à mes propriétés supportedInterfaceOrientation.

Cependant, fonctionner en mode portrait n'a vraiment aucun sens pour mon application. J'avais pensé que je pouvais utiliser shouldAutorotateToInterfaceOrientation pour permettre à l'application de "prendre en charge le portrait", mais seulement être autorisé à faire pivoter vers portrait dans cette seule vue. Mais maintenant, cette méthode est obsolète et je ne peux pas utiliser la même technique avec shouldAutorotate.

Quelqu'un a-t-il des idées sur la façon de contourner ce problème sous iOS 6.0?

41
jenonen

iOS 6.1 - corrigé

Depuis iOS 6.1, cela ne se produit plus , il est très important de suivre mes conseils afin d'éviter un plantage sous iOS 6.0.x, ci-dessous s'applique toujours à cela.


solution de contournement iOS 6.0.x

Il s'agit en fait d'un bogue dans iOS 6.0, cela devrait être corrigé dans les futures versions d'iOS.

Un ingénieur de Apple a expliqué ce bogue et une solution de contournement ici: https://devforums.Apple.com/message/731764

Cela se produit parce que l'application ne souhaite que l'orientation paysage, mais certains contrôleurs Cocoa Touch View nécessitent strictement l'orientation Portrait, ce qui est l'erreur - non pas qu'ils devraient exiger plus que Portrait, mais leur interprétation des exigences de l'application.

Un exemple de ceci peut être le suivant:

l'application iPad prenant en charge le paysage affiche uniquement un UIImagePickerController via un UIPopoverController. UIImagePickerController nécessite une orientation Portrait, mais l'application ne force que le paysage. Erreur et ... plantage

D'autres frameworks qui ont été signalés comme problématiques incluent le contrôleur de vue de connexion Game Center.

La solution de contournement est assez simple mais pas idéale ... Vous conservez les orientations correctes déclarées dans votre volet info info.plist/projet, mais dans la classe Application Delegate vous déclarez autoriser toutes les orientations.

Maintenant, chaque contrôleur de vue que vous ajoutez à la fenêtre doit spécifier lui-même qu'il ne peut s'agir que de paysage. Veuillez vérifier le lien pour plus de détails.


Je ne peux pas souligner combien vous ne devriez pas sous-classer UIImagePickerController car la solution acceptée insiste pour que vous le fassiez.

enter image description here

L'important ici est " Cette classe est destinée à être utilisée telle quelle et ne prend pas en charge le sous-classement ".


Dans mon cas, j'ai ajouté cela au délégué de mon application (j'ai une application paysage uniquement), cela indique au sélecteur d'images qu'elle peut afficher, car le portrait est pris en charge:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    return UIInterfaceOrientationMaskAll;
}

Et puis dans mon contrôleur de vue qui se trouvait être un UINavigationController, j'ai inclus une catégorie avec ce qui suit:

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscape;
}

Maintenant, mon application ne tourne pas, et le sélecteur d'images demande au délégué s'il peut s'afficher en portrait et on lui dit que ça va. Donc tout se passe bien.

80
Daniel

J'ai eu un problème similaire, mais dans une application paysage iPad. Je présentais le sélecteur d'images dans un popover. Il s'est écrasé sous iOS 6. L'erreur a suggéré que le sélecteur voulait un portrait, mais l'application ne proposait que des vues de paysage, et ... surtout ... le sélecteur shouldRotate retournait OUI.

Je l'ai ajouté à mon ViewControllerClass.m qui crée le sélecteur

@interface NonRotatingUIImagePickerController : UIImagePickerController

@end

@implementation NonRotatingUIImagePickerController

- (BOOL)shouldAutorotate
{
    return NO;
}

@end

puis utilisé cette classe à la place

UIImagePickerController *imagePicker = [[NonRotatingUIImagePickerController alloc] init];
[myPopoverController setContentViewController:imagePicker animated:YES];

Cela a résolu le problème pour moi. Votre situation est un peu différente, mais cela ressemble fondamentalement à la même erreur.

41
eclux

Bien que le sous-classement UIImagePickerController fonctionne, une catégorie est une meilleure solution:

    @implementation UIImagePickerController (NonRotating)

    - (BOOL)shouldAutorotate
    {
        return NO;
    }

    -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
    {
        return UIInterfaceOrientationPortrait;
    }

    @end
26
JonahGabriel

Rapports depuis iOS 7.1:

En plus de ce que spécifient les réponses ci-dessus, il semble que vous devez absolument activer les modes portrait dans info.plist.

Sans cela, aucun des codes/correctifs ci-dessus n'a fonctionné pour moi.

1