iOS6: supportedInterfaceOrientations ne fonctionne pas (est invoqué mais l'interface tourne toujours)

Dans mon application, j'ai plusieurs vues, certaines vues doivent prendre en charge le portrait et le paysage, tandis que d'autres ne doivent prendre en charge que le mode portrait. Ainsi, dans le résumé du projet, j'ai choisi toutes les orientations.

Le code ci-dessous a fonctionné pour désactiver le mode paysage sur un controller de vue donné avant iOS 6:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } 

Comme shouldAutorotateToInterfaceOrientation était obsolète dans iOS6, j'ai remplacé ce qui précède par:

 -(NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMask.Portrait; } 

Cette méthode est correctement appelée lorsque la vue apparaît (je peux définir un point d'arrêt pour l'assurer), mais l'interface tourne toujours en mode paysage, même si je ne renvoie le masque que pour les modes portrait. Qu'est-ce que je fais mal?

Il semble qu'il est actuellement impossible de build une application qui a différentes exigences d'orientation par vue. Il semble ne respecter que les orientations spécifiées dans le résumé du projet.

Si vous utilisez UINavigationController comme controller de window racine , ce sera son shouldAutorotate & supportedInterfaceOrientations qui seront appelés.

Idem si vous utilisez un UITabBarController , et ainsi de suite.

Donc, la chose à faire est de sous-classr votre controller de navigation / tabbar et de surcharger ses methods shouldAutorotate & supportedInterfaceOrientations .

essayez de modifier ce code dans AppDelegate.m

 // self.window.rootViewController = self.navigationController; [window setRootViewController:navigationController]; 

c'est la réponse complète

shouldAutorotateToInterfaceOrientation n'étant pas appelé dans iOS 6

XD

Dans mon cas, j'ai UINavigationController et mon controller de vue à l'intérieur. J'ai dû sous-classr UINavigationController et, pour ne supporter que Portrait, append cette méthode:

 - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; } 

Donc, dans la sous-class UINavigationController, je dois vérifier quelle orientation est prise en charge par le topViewController actuel.

 - (NSUInteger)supportedInterfaceOrientations { return [[self topViewController] supportedInterfaceOrientations]; } 

Une chose que j'ai trouvée est que si vous avez une ancienne application qui fonctionne encore

 [window addSubView:viewcontroller.view]; //This is bad in so may ways but I see it all the time... 

Vous devrez mettre à jour cela pour:

 [window setRootViewController:viewcontroller]; //since iOS 4 

Une fois que vous faites cela, l'orientation devrait recommencer à fonctionner.

Le meilleur moyen pour iOS6 est spécifiquement noté dans "iOS6 By Tutorials" par l'équipe de Ray Wenderlich – http://www.raywenderlich.com/ et vaut mieux que sous-classr UINavigationController pour la plupart des cas.

J'utilise iOS6 avec un storyboard qui inclut un set UINavigationController comme controller de vue initial.

//AppDelegate.m – cette méthode n'est pas disponible pré-iOS6 malheureusement

 - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{ NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown; if(self.window.rootViewController){ UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject]; orientations = [presentedViewController supportedInterfaceOrientations]; } return orientations; } 

//MyViewController.m – returnne toutes les orientations que vous voulez supporter pour chaque UIViewController

 - (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; } 

Comme indiqué par d'autres si vous utilisez un UINavigationController et que vous voulez personnaliser plusieurs vues, vous voudrez sous-classr UINavigationController et vous assurer que vous avez ces deux composants:

 @implementation CustomNavigationController // ------------------------------------------------------------------------------- // supportedInterfaceOrientations: // Overridden to return the supportedInterfaceOrientations of the view controller // at the top of the navigation stack. // By default, UIViewController (and thus, UINavigationController) always returns // UIInterfaceOrientationMaskAllButUpsideDown when the app is run on an iPhone. // ------------------------------------------------------------------------------- - (NSUInteger)supportedInterfaceOrientations { return [self.topViewController supportedInterfaceOrientations]; } // ------------------------------------------------------------------------------- // shouldAutorotate // Overridden to return the shouldAutorotate value of the view controller // at the top of the navigation stack. // By default, UIViewController (and thus, UINavigationController) always returns // YES when the app is run on an iPhone. // ------------------------------------------------------------------------------- - (BOOL)shouldAutorotate { return [self.topViewController shouldAutorotate]; } 

Ensuite, dans toute vue qui est un portrait seulement, vous devez inclure:

 - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } 

Et dans tout sharepoint vue qui est tout sauf à l'envers:

 - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAllButUpsideDown; } 

Fondamentalement comme quelqu'un a déclaré ci-dessus, mais plus en détail:

  1. Créer un nouveau file qui est une sous-class de UINavigationController
  2. Accédez à votre storyboard, puis click le controller de navigation, définissez sa class sur celle que vous venez de créer.
  3. Dans cette class (file .m), ajoutez le code suivant pour qu'il rest en mode portrait:

     (BOOL)shouldAutorotate { return NO; } (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } 

Cela a fonctionné pour moi

Ce code a fonctionné pour moi:

 -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } 

iPhone / iPad App Orientation vérifier ma propre réponse

La meilleure façon dont je pense est de faire une catégorie plutôt que de sous- UINavigationController ou UITabbarController

votre UINavigationController + Rotation.h

 #import <UIKit/UIKit.h> @interface UINavigationController (Rotation) @end 

votre UINavigationController + Rotation.m

 #import "UINavigationController+Rotation.h" @implementation UINavigationController (Rotation) -(BOOL)shouldAutorotate { return [[self.viewControllers lastObject] shouldAutorotate]; } -(NSUInteger)supportedInterfaceOrientations { return [[self.viewControllers lastObject] supportedInterfaceOrientations]; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation]; } @end 

Essayez de faire en sorte que tous vos controllers importent cette catégorie et que cela fonctionne comme un charme. Vous pouvez même faire en sorte qu'un controller ne tourne pas et pousse un autre controller qui tournera.

Essayez d'append la méthode shouldAutorotate

Tout d'abord, pour que votre application fonctionne en mode uniquement, vous devez returnner UIInterfaceOrientationMaskLandscape . Dans le cas où vous voulez garder seulement le mode portrait, vous faites les choses correctement.

Ajoutez simplement la key UISupportedInterfaceOrientations dans Info.plist et affectez les valeurs d'orientation de l'interface que votre application a l'intention de conserver.

De plus, vous devriez returnner false à partir de shouldAutoRotate au cas où vous voudriez éviter complètement la rotation automatique. Mais je vous suggère de renvoyer true à partir d'ici et de spécifier les orientations correctes dans la méthode supportedInterfaceOrientations .

J'ai la même situation que toi. Je sais que vous avez déjà accepté une réponse, mais je pensais en append une autre de toute façon. C'est ainsi que je comprends la nouvelle version du système de rotation pour fonctionner. Le controller de vue racine est le seul controller de vue à être appelé. Le raisonnement, je crois, est qu'avec les controllers de vue enfants, il n'est pas toujours judicieux de faire pivoter leurs vues, car elles restront dans le cadre du controller de vue racine de toute façon.

Alors, que se passe-t-il? Tout d'abord, shouldAutorotate est appelé sur le controller de la vue racine . Si NO est returnné alors tout s'arrête. Si YES est renvoyé, la méthode supportedInterfaceOrientations est appelée. Si l'orientation de l'interface est confirmée dans cette méthode et les orientations globales sockets en charge à partir de Info.plist ou du délégué d'application, la vue pivote. Avant la rotation, la méthode shouldAutomaticallyForwardRotationMethods est interrogée. Si YES (par défaut), tous les enfants recevront les methods will et didRotateTo... ainsi que le parent (et ils le transmettront à leur tour à leurs enfants).

Ma solution (jusqu'à ce qu'il y en ait une plus eloquent) consiste à interroger le dernier controller de vue enfant au cours de la méthode supportedInterfaceOrientations et à renvoyer sa valeur. Cela me permet de faire pivoter certaines zones tout en gardant les autres portrait uniquement. Je me rends count que c'est fragile, mais je ne vois pas d'autre moyen qui ne consiste pas à compliquer les choses avec des appels d'events, des callbacks, etc.

Si vous utilisez UINavigationController , vous devez implémenter shouldAutorotate et supportedInterfaceOrientations dans la sous-class de UINavigationController .

Ceux-ci sont capables de contrôler en deux étapes, si shouldAutorotate renvoie YES puis efficacement supportedInterfaceOrientations . C'est une très belle combinaison.

Dans cet exemple, mes vues sont principalement Portrait sauf CoverFlowView et PreviewView. Le transfert CoverFlowView vers PreviewView, PreviewView veut suivre la rotation de CoverFlowCView.

 @implementation MyNavigationController -(BOOL)shouldAutorotate { if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromSsortingng(@"PreviewView")]) return NO; else return YES; } -(NSUInteger)supportedInterfaceOrientations { if ([[self.viewControllers lastObject] isKindOfClass:NSClassFromSsortingng(@"CoverFlowView")]) return UIInterfaceOrientationMaskAllButUpsideDown; else return UIInterfaceOrientationMaskPortrait; } ... @end 

ma solution: sous- UINavigationController et le définir comme window.rootViewController

le viewcontroller supérieur de la hiérarchie prendra le contrôle de l'orientation, quelques exemples de code: sous-classé UINavigationController

Les réponses ici m'ont pointé dans la direction correcte bien que je ne puisse pas l'get en coupant simplement et collant parce que j'utilise UINavigationControllers à l'intérieur d'un UITabBarController. Donc, ma version dans AppDelegate.m ressemble à ceci, qui fonctionnera pour UITabBarControllers, UINavigationControllers ou UINavigationControllers dans un UITabBarController. Si vous utilisez d'autres controllers de confinement personnalisés, vous devrez les append ici (ce qui est une sorte de déception).

 - (UIViewController*)terminalViewController:(UIViewController*)viewController { if ([viewController isKindOfClass:[UITabBarController class]]) { viewController = [(UITabBarController*)viewController selectedViewController]; viewController = [self terminalViewController:viewController]; } else if ([viewController isKindOfClass:[UINavigationController class]]) { viewController = [[(UINavigationController*)viewController viewControllers] lastObject]; } return viewController; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { NSUInteger orientations = UIInterfaceOrientationMaskPortrait; UIViewController* viewController = [self terminalViewController:window.rootViewController]; if (viewController) orientations = [viewController supportedInterfaceOrientations]; return orientations; } 

Une autre chose importante à noter est que vous devez surcharger supportedInterfaceOrientations dans vos sous-classs UIViewController ou qu'il sera par défaut à ce que vous avez spécifié dans votre Info.plist.