Les orientations prises en charge n'ont pas d'orientation commune avec l'application et shouldAutorotate renvoie OUI '

92

Mon application (iPad; iOS 6) est une application uniquement en mode paysage, mais lorsque j'essaie d'utiliser un UIPopoverController pour afficher la photothèque, cela génère cette erreur: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.j'ai essayé de changer une grande partie du code mais je n'ai pas eu de chance.

Aube du destin
la source
1
vous devriez accepter une réponse. il y a beaucoup de gens pour de l'aide et pour d'autres personnes qui ont le même problème, cela aide lorsque vous marquez la bonne réponse pour votre problème!
brush51
1
Non! aucune solution ne fonctionne sur iOS 7 :( (headbang)
AsifHabib
Meilleure réponse ici stackoverflow.com/questions/20468335/…
Damien Romito

Réponses:

94

Dans IOS6, vous avez pris en charge les orientations d'interface à trois endroits:

  1. Le .plist (ou écran de résumé de la cible)
  2. Votre UIApplicationDelegate
  3. UIViewController qui est affiché

Si vous obtenez cette erreur, c'est probablement parce que la vue que vous chargez dans votre UIPopover ne prend en charge que le mode portrait. Cela peut être causé par Game Center, iAd ou votre propre vue.

S'il s'agit de votre propre vue, vous pouvez le corriger en remplaçant supportedInterfaceOrientations sur votre UIViewController:

- (NSUInteger) supportedInterfaceOrientations
{
     //Because your app is only landscape, your view controller for the view in your
     // popover needs to support only landscape
     return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

S'il ne s'agit pas de votre propre vue (comme GameCenter sur l'iPhone), vous devez vous assurer que votre .plist prend en charge le mode portrait. Vous devez également vous assurer que votre UIApplicationDelegate prend en charge les vues affichées en mode portrait. Vous pouvez le faire en modifiant votre .plist, puis en remplaçant le supportedInterfaceOrientation sur votre UIApplicationDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
Snickers
la source
3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightest UIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightégal àUIInterfaceOrientationMaskLandscape
Valerii Pavlov
4
Ou utilisez simplement UIInterfaceOrientationMaskAll.
Mark Wang
Parfait. Même si un popover "portrait uniquement" fonctionnera en mode paysage, il ne peut pas présenter un contrôleur de vue uniquement en mode paysage.
Neal Ehardt
Non! Solution n'a pas travaillé sur iOS 7 :(. Stackoverflow.com/questions/23005351/...
AsifHabib
A travaillé sur iOS 8. Cependant, a dû ajouter le support de portrait à plist. Je vous remercie.
Yaroslav
65

Après avoir passé beaucoup de temps à chercher un moyen d'éviter les sous-classements et d'ajouter une tonne de code, voici ma solution de code en une ligne.

Créez une nouvelle catégorie UIImagePickerController et ajoutez

-(BOOL)shouldAutorotate{
    return NO;
}

C'est tout les gens!

Dr Luiji
la source
1
A travaillé pour moi aussi, je n'ai pas complètement testé mais semble faire l'affaire jusqu'à présent.
migs647
2
Cela semble être la meilleure solution.
Julian
2
Travaux! C'est génial et cela m'a vraiment aidé à la rigueur. Merci Dr Luiji !!
brack
1
Agréable. Fonctionne pour moi sur iOS 6. Vous pouvez également le rendre configurable dans la catégorie pour une flexibilité totale.
Jared Egan
3
ne fonctionne pas sous iOS7, la méthode de catégorie n'est même pas appelée (bien que incluse dans le pch)
Peter Lapisu
43

Dans un autre cas, ce message d'erreur peut apparaître. J'ai cherché pendant des heures jusqu'à ce que je trouve le problème. Ce fil a été très utile après l'avoir lu plusieurs fois.

Si votre contrôleur de vue principal est tourné en orientation paysage et que vous invoquez un contrôleur de vue secondaire personnalisé qui devrait être affiché en orientation portrait, ce message d'erreur peut se produire lorsque votre code ressemble à ceci:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

Le piège ici était l'intellisense de xcode suggéré "UIInterfaceOrientationPortrait" et je m'en fichais. À première vue, cela semblait correct.

Le bon masque est nommé

UIInterfaceOrientationMaskPortrait

Faites attention au petit infixe "Mask" , sinon votre sous-vue se retrouvera avec une exception et le message d'erreur mentionné ci-dessus.

Les nouvelles énumérations sont légèrement décalées. Les anciennes énumérations renvoient des valeurs invalides!

(dans UIApplication.h, vous pouvez voir la nouvelle déclaration: UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait) )

La solution est:

- (BOOL)shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {

    // ATTENTION! Only return orientation MASK values
    // return UIInterfaceOrientationPortrait;

    return UIInterfaceOrientationMaskPortrait;
} 

En utilisation rapide

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
JackPearse
la source
5
m'est arrivé pour la même raison
ChenXin
J'aurais aimé qu'Apple fasse juste le type de retour UIInterfaceOrientationMask afin que ce soit un peu plus évident ce qui doit être retourné.
LightningStryk
La réponse de Jackpearse semble correcte. Mais quand on regarde dans info.plist, il y a UISupportedInterfaceOrientations avec UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight. Pas MASQUE ici
onmyway133
1
@onmyway: C'est vrai, les valeurs plist n'ont pas changé. Dans la version iOS précédente, Apple utilisait les valeurs de masque «non» à l'intérieur du code. Ce sont des trucs hérités. Je suppose qu'Apple change un peu les valeurs plist en interne maintenant.
JackPearse
Mon application fonctionnait sans ce problème de plantage sur un simulateur iPad de Xcode 6.2. Et il s'est écrasé après la mise à niveau vers Xcode 6.3 il y a quelques jours. Maintenant, cette solution résout mon problème. Merci beaucoup :-)
Golden Thumb
22

J'ai eu un problème similaire lors de la présentation du sélecteur d'images dans une application de paysage uniquement. Comme suggéré par le Dr Luiji, j'ai ajouté la catégorie suivante au début de mon contrôleur.

// This category (i.e. class extension) is a workaround to get the
// Image PickerController to appear in landscape mode.
@interface UIImagePickerController(Nonrotating)
- (BOOL)shouldAutorotate;
@end

@implementation UIImagePickerController(Nonrotating)

- (BOOL)shouldAutorotate {
  return NO;
}
@end

Il est plus simple d'ajouter ces lignes juste avant la @implementation de votre fichier ViewController .m.

Trausti Kristjansson
la source
J'ai une application portrait uniquement! et je veux afficher Appareil photo en mode Paysage. Toute solution?????
AsifHabib
Trausti n'a pas fonctionné? J'ai le même problème et j'ai essayé votre code mais j'ai toujours la même exception ... j'ai également mis un point d'arrêt sur la méthode de catégorie UIimagePickerView shouldAutorotate pour y parvenir et renvoie non, mais je donne toujours cette exception .... Mon application est une application en mode paysage ... s'il vous plaît aidez-moi
Vishal16
Fonctionne également pour forcer SKStoreProductViewController à présenter en portrait lorsque toute l'application est en paysage dans iOS 8. En vous remerciant.
Yaroslav
11

Je rencontrais le même message d'erreur dans mon code. J'ai trouvé ça, c'est un bug rapporté par Apple:

https://devforums.apple.com/message/731764#731764

Sa solution est de le corriger dans l'AppDelegate. Je l'ai implémenté et ça marche pour moi!

Robby
la source
Au fait, j'ai trouvé ceci à l'origine sur: stackoverflow.com/questions/12522491/…
Robby
C'était la bonne réponse, directement d'Apple, et ensuite je devais suivre les mêmes instructions mais le faire dans Swift pour une application ciblant iOS 8. Tout fonctionne très bien. AppDelegate définit supportedInterfaceOrientationsForWindow à la fois sur Paysage et Portrait, chaque jeu de fichiers rapide individuel remplace func supportedInterfaceOrientations sur Paysage uniquement pour que la vue ne tourne pas, mais lorsqu'une vue portrait (dans mon cas SKStoreProductViewController) doit se charger, cela fonctionne!
RanLearns
Bon sang, il y a tellement de solutions suggérées, et celle-ci n'a de loin pas les points les plus élevés, mais c'est en effet la bonne. Testé sur iOS 10 et 9. Rien d'autre ne fonctionne.
Demian Turner
6

J'ai eu le même problème et cette réponse https://stackoverflow.com/a/12523916 fonctionne pour moi. Je me demande s'il existe une solution plus élégante.

Mon code:

UIImagePickerController  *imagePickerController = [[NonRotatingUIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

UIPopoverController  *popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];    

[popoverVC presentPopoverFromRect:frame   // did you forget to call this method?
                           inView:view
         permittedArrowDirections:UIPopoverArrowDirectionAny
                         animated:YES];
poète
la source
J'ai essayé de faire cela, mais lorsque je clique sur le bouton pour appeler le code mais que rien ne s'affiche, j'ai également essayé d'ajouter @interface NonRotatingUIImagePickerController : UIImagePickerController @end @implementation NonRotatingUIImagePickerController - (BOOL)shouldAutorotate { return NO; } @endau code mais mon code ne détectait pas NonRotatingUIImagePickerController.
Destiny Dawn
1
Qu'à cela ne tienne, il détecte NonRotatingUIImagePickerController maintenant mais rien ne s'affiche toujours ... @poetowen
Destiny Dawn
4

iOS 8 - vous pouvez utiliser UIModalPresentationPopover sans aucun piratage à afficher dans un popover. Pas idéal mais mieux que rien.

imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.popoverPresentationController.sourceView = self.view;
imagePicker.popoverPresentationController.sourceRect = ((UIButton *)sender).frame;

Edit: essayez peut-être les différents UIModalPresentationStyles - peut-être que d'autres fonctionneront en paysage.

derbs
la source
3
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.
Suhail Bhat
la source
2

Une autre option qui a résolu mes problèmes était de créer une sous-classe de UIImagePickerController et de remplacer la méthode ci-dessous

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

Utilisez ceci au lieu de UIImagePickerController et tout fonctionne correctement.

EquiAvia Tech
la source
1

Créer une catégorie est vraiment utile pour corriger ce bogue. Et n'oubliez pas d'importer votre catégorie créée. Cela ajoutera la méthode manquante à UIImagePickerController et sur iOS 6, cela limitera son fonctionnement dans Portrait uniquement comme l'indique la documentation btw.

Les autres solutions peuvent avoir fonctionné. Mais avec le SDK pour iOS 8.x compilé pour être déployé sur iOS 6.1, cela semble être la voie à suivre.

Le fichier .h:

#import <UIKit/UIKit.h>

@interface UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate;
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;

@end

Le fichier .m:

#import "UIImagePickerController+iOS6FIX.h"

@implementation UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate {
    return NO;
}

- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

@end
Helge Staedtler
la source
1

Swift 3

let imagePicker = UIImagePickerController()

imagePicker.modalPresentationStyle = .popover
imagePicker.popoverPresentationController?.sourceView = sender // you can also pass any view 

present(imagePicker, animated: true)
zombi
la source
0

J'ai rencontré ce problème plantage lors de la conversion UIInterfaceOrientationPortraitde manière UIInterfaceOrientationMaskPortraitimplicite comme une valeur de retour.

Plus de fond de code UIPageViewControllerDelegate, juste pour info pour vous tous.

 -(UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:
(UIPageViewController *)pageViewController
{
    # return UIInterfaceOrientationPortrait;    # wrong
    return UIInterfaceOrientationMaskPortrait;  # correct
}
Itachi
la source
0

Je viens de résoudre le problème de Swift 4.x

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    configureVideoOrientation()
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: nil, completion: { [weak self] _ in
        self?.configureVideoOrientation()
    })
}

private func configureVideoOrientation() {
    guard let previewLayer = self.previewLayer, let connection = previewLayer.connection else { return }
    if connection.isVideoOrientationSupported {
        let orientation = UIApplication.shared.statusBarOrientation
        switch (orientation) {
        case .portrait:
            previewLayer.connection?.videoOrientation = .portrait
        case .landscapeRight:
            previewLayer.connection?.videoOrientation = .landscapeRight
        case .landscapeLeft:
            previewLayer.connection?.videoOrientation = .landscapeLeft
        case .portraitUpsideDown:
            previewLayer.connection?.videoOrientation = .portraitUpsideDown
        default:
            previewLayer.connection?.videoOrientation = .portrait
        }

        previewLayer.frame = self.view.bounds
    }
}

Merci les gars pour vos réponses également. Je viens de couper le code travaillé et de le refactoriser simplement.

aterechkov
la source
0

Swift 4 et plus en supposant que toute l'application est en paysage et que vous devez présenter un seul contrôleur en portrait. Dans le contrôleur de vue qui doit être portrait, ajoutez ce qui suit:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
Gal Blank
la source