web-dev-qa-db-fra.com

Les orientations prises en charge n'ont pas d'orientation commune avec l'application, et devraient-elles être retournées par OUI?

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, cette erreur renvoie cette erreur: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES. J'ai essayé de changer beaucoup de code mais je n'ai pas eu de chance.

90
Destiny Dawn

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

  1. Le .plist (ou écran de résumé cible)
  2. Votre UIApplicationDelegate
  3. UIViewController en cours d'affichage

Si vous obtenez cette erreur, il est fort probable 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 y remédier en remplaçant les interfaces 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 (telle que GameCenter sur 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 nom de fichier .plist, puis en remplaçant le supportedInterfaceOrientation sur votre UIApplicationDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
92
Snickers

Après avoir passé beaucoup de temps à chercher un moyen d'éviter les sous-classes 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!

64
Dr.Luiji

Il y a un autre cas, ce message d'erreur peut apparaître. Je cherchais 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 pivoté en orientation paysage et que vous appelez un contrôleur de vue secondaire personnalisé qui doit ê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 foutais. Au premier abord, cela semblait être correct.

Le bon masque est nommé

UIInterfaceOrientationMaskPortrait

Soyez conscient du petit infixe "Masque", sinon votre sous-vue se retrouvera avec une exception et le message d'erreur mentionné ci-dessus.

Les nouveaux enums sont un peu décalés. Les anciens enums 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;
} 

Dans Swift utiliser

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
43
JackPearse

J'ai eu un problème similaire lors de la présentation du sélecteur d'images dans une application de type 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 facile d'ajouter ces lignes juste avant la @implémentation de votre fichier ViewController .m.

22

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

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

Sa solution consiste à résoudre le problème dans AppDelegate. Je l'ai implémenté et ça marche pour moi!

11
Robby

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];
6
poetowen

iOS 8 - vous pouvez utiliser UIModalPresentationPopover sans aucun piratage à afficher dans une fenêtre 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 plus fonctionnera dans le paysage.

4
derbs
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.
3
Suhail Bhat

Une autre option qui a résolu mes problèmes a été 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 à la place de UIImagePickerController et tout fonctionne bien.

2
EquiAvia Tech

Créer une catégorie est vraiment utile pour résoudre ce problème. Et n'oubliez pas d'importer votre catégorie créée. Cela ajoutera la méthode manquante à UIImagePickerController et, sur iOS 6, le restreindra à fonctionner dans Portrait uniquement, car la documentation indique btw.

Les autres solutions ont peut-être fonctionné. Mais avec SDK pour iOS 8.x compilé pour se déployer 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
1
Helge Staedtler

Swift

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)
1
zombie

Je viens de résoudre le problème pour 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 aussi. Je viens de couper le code travaillé et simplement le refactoriser.

0
atereshkov

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 devant être en mode portrait, ajoutez ce qui suit:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

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

J'ai rencontré ce problème d'incident lorsque convertissant UIInterfaceOrientationPortrait en UIInterfaceOrientationMaskPortrait implicitement en tant que valeur de retour.

Plus d'informations sur le code sur UIPageViewControllerDelegate, juste pour votre information.

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