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:
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.