J'ai une application iPhone qui utilise un UINavigationController
pour présenter une interface d'exploration: d'abord une vue, puis une autre, jusqu'à quatre niveaux de profondeur. Je veux que les trois premières vues soient limitées à l'orientation portrait et que seule la dernière vue devrait pouvoir pivoter en paysage. Lorsque vous revenez de la quatrième vue à la troisième et que la quatrième vue était en orientation paysage, je veux que tout revienne en portrait.
Dans iOS 5, j'ai simplement défini shouldAutorotateToInterfaceOrientation:
dans chacun de mes contrôleurs de vue pour retourner OUI pour les orientations autorisées. Tout a fonctionné comme décrit ci-dessus, y compris le retour au portrait même si l'appareil était maintenu en orientation paysage lors du retour du contrôleur de vue n ° 4 au n ° 3.
Dans iOS 6, tous les contrôleurs de vue tournent en paysage, cassant ceux qui n'étaient pas censés le faire. Les notes de publication d'iOS 6 disent
Plus de responsabilités sont transférées à l'application et au délégué d'application. Désormais, les conteneurs iOS (tels que
UINavigationController
) ne consultent pas leurs enfants pour déterminer s'ils doivent effectuer une rotation automatique. [...] Le système demande au contrôleur de vue plein écran le plus haut (généralement le contrôleur de vue racine) pour ses orientations d'interface prises en charge chaque fois que l'appareil tourne ou chaque fois qu'un contrôleur de vue est présenté avec le style de présentation modale plein écran. De plus, les orientations prises en charge ne sont récupérées que si ce contrôleur de vue renvoie YES à partir de sashouldAutorotate
méthode. [...] Le système détermine si une orientation est prise en charge en croisant la valeur renvoyée par lasupportedInterfaceOrientationsForWindow:
méthode de l'application avec la valeur renvoyée par lasupportedInterfaceOrientations
méthode du contrôleur plein écran le plus haut.
J'ai donc sous UINavigationController
- classé , donné ma MainNavigationController
propriété booléenne landscapeOK
et utilisé ceci pour renvoyer les orientations autorisées dans supportedInterfaceOrientations
. Ensuite, dans chacune des viewWillAppear:
méthodes de mes contrôleurs de vue , j'ai une ligne comme celle-ci
[(MainNavigationController*)[self navigationController] setLandscapeOK:YES];
pour me dire MainNavigationController
le comportement souhaité.
Voici la question: si je navigue maintenant vers ma quatrième vue en mode portrait et que je retourne le téléphone, il tourne en paysage. Maintenant, j'appuie sur le bouton retour pour revenir à ma troisième vue qui est censée ne fonctionner qu'en portrait. Mais ça ne revient pas. Comment faire ça?
j'ai essayé
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]
dans la viewWillAppear
méthode de mon troisième contrôleur de vue, mais il ne fait rien. Est-ce la mauvaise méthode pour appeler ou peut-être le mauvais endroit pour l'appeler ou devrais-je mettre en œuvre le tout d'une manière totalement différente?
la source
Ajouter un CustomNavigationController
Remplacez ces méthodes:
Maintenant, ajoutez toutes les orientations dans le plist
Dans le contrôleur de vue, ajoutez uniquement les éléments requis:
ces méthodes remplacent les méthodes du contrôleur de navigation
la source
ViewController
en mode Portrait et le mienViewController
est en mode Paysage et portrait. Je donne également un support à la fois dans iOS 5.0 et iOS 6.0.C'est pourquoi je suis confus pour travailler, mais c'est une excellente solution. J'ajoute CustomNavigationController dans mon contrôleur de vue racine et apporte un support en fonction de mes besoins. Encore merci.Après avoir examiné chaque réponse dans d'innombrables questions similaires sur le SO, aucune des réponses n'a fonctionné pour moi, mais elles m'ont donné quelques idées. Voici comment j'ai fini par résoudre le problème:
Tout d'abord, assurez-vous que vos orientations d'interface prises en charge dans la cible de votre projet contiennent toutes les orientations souhaitées pour votre vue rotative.
Ensuite, créez une catégorie de
UINavigationController
(puisque Apple dit de ne pas la sous-classer):Importez cette catégorie et le contrôleur de vue que vous souhaitez pouvoir faire pivoter (que je vais appeler
RotatingViewController
) vers votre contrôleur de vue de plus haut niveau, qui devrait contenir votre contrôleur de navigation. Dans ce contrôleur de vue, implémentezshouldAutorotate
comme suit. Notez que cela ne doit pas être le même contrôleur de vue que vous souhaitez faire pivoter.Enfin, dans votre
RotatingViewController
, implémentezshouldAutorotate
etsupportedInterfaceOrientations
comme suit:La raison pour laquelle vous devez faire cela est parce que iOS 6 donne le contrôle de la rotation au contrôleur de vue racine au lieu du contrôleur de vue de dessus. Si vous souhaitez que la rotation d'une vue individuelle se comporte différemment des autres vues de la pile, vous devez écrire un cas spécifique pour elle dans le contrôleur de vue racine.
la source
Je n'ai pas assez de réputation pour commenter la réponse de @ Brian, je vais donc ajouter ma note ici.
Brian a mentionné qu'iOS6 donne le contrôle de rotation au rootViewController - cela pourrait non seulement être un UINavigationController comme mentionné mais aussi un UITabBarController, ce qui était pour moi. Ma structure ressemble à ceci:
J'ai donc ajouté les méthodes d'abord dans un UITabBarController personnalisé, puis dans un UINavigationController personnalisé et enfin dans le UIViewController spécifique.
Exemple de UITabBarController et UINavigationController:
la source
Je voudrais donner une réponse partielle à ma propre question. J'ai trouvé la ligne de code suivante, utilisée dans la
viewWillAppear
méthode de mon troisièmeUIViewController
, pour fonctionner:Mais je n'aime pas vraiment cette solution. Il utilise une astuce pour attribuer une propriété en lecture seule qui, selon la documentation Apple, représente l' orientation physique de l'appareil. C'est comme dire à l'iPhone de passer à la bonne orientation dans la main de l'utilisateur.
Je suis très tenté de laisser cela dans mon application car cela fonctionne simplement. Mais cela ne me semble pas bien, alors j'aimerais laisser la question ouverte pour une solution propre.
la source
C'est ce que j'utilise pour la prise en charge de l'orientation dans iOS 6.0
la source
Étant donné que c'est un fil très apprécié. J'ai pensé ajouter ce que je crois être la réponse la plus simple. Cela fonctionne pour ios8 et plus
et
C'est tout. Prendre plaisir!
Oh, et mes ViewControllers sont intégrés dans un contrôleur de navigation, que je n'avais pas besoin de sous-classer ou de configurer en aucune façon.
la source
Cela peut ne pas fonctionner pour tout le monde, mais cela fonctionne très bien pour moi. Au lieu de mettre en œuvre ...
in viewWillAppear dans tous mes contrôleurs, j'ai décidé de centraliser ce processus à l'intérieur de ma sous-classe UINavigationController en remplaçant la méthode UINavigationControllerDelegate
navigationController:willShowViewController:animated:
J'ai trouvé que cette méthode de délégué n'est pas appelée lors du saut d'un VC hors de la pile de navigation. Ce n'était pas un problème pour moi car je gère la fonctionnalité de retour à partir de ma sous-classe UINavigationController afin que je puisse définir les boutons et les actions de la barre de navigation appropriés pour des VC spécifiques comme celui-ci ...
Voici à quoi
back
ressemble ma méthode pour gérer la sortie du VC de la pile et pour définir la préférence de rotation appropriée ...Donc, comme vous pouvez le voir, tout ce qui se passe, c'est que je commence par me définir deux propriétés ...
dans
navigationController:willShowViewController:animated:
lequel déterminera quelles sont les orientations prises en charge dans ce CV qui est sur le point d'être présenté. Lors de l'éclatement d'un VC, ma méthode "back" personnalisée est appelée et je règle ensuite isLandscapeOK sur ce qui a été stocké via la valeur VCLandscapeOK précédente.Comme je l'ai dit, cela peut ne pas fonctionner pour tout le monde, mais cela fonctionne très bien pour moi et je n'ai pas à me soucier d'ajouter du code à chacun de mes contrôleurs de vue, j'ai pu tout garder centralisé dans la sous-classe UINavigationController.
J'espère que cela aide quelqu'un comme moi. Merci, Jeremy.
la source
Accédez à votre fichier Info.plist et effectuez le changement
la source
Vous souhaitez forcer le portrait d'application iOS 6 uniquement, vous pouvez ensuite ajouter à une sous-classe UIViewController ci-dessous les méthodes
la source
NSUInteger
jette un avertissement bien qu'il s'agisse du type var correct. si vous avez un TOC, utilisezUIInterfaceOrientationMask
plutôt.Je voulais que tous mes VC soient verrouillés en orientation portrait, sauf un. C'est ce qui a fonctionné pour moi.
Dans le contrôleur de vue racine, détectez le type de contrôleur de vue qui se trouve en haut de la fenêtre et définissez l'orientation de l'application en conséquence dans la méthode supportedInterfaceOrientations . Par exemple, j'avais besoin de mon application pour pivoter uniquement lorsque la vue Web était au-dessus de la pile. Voici ce que j'ai ajouté dans mon rootVC:
la source
[[Utils getAppDelegate] appNavigationController]
. Utils, je suppose que c'est une classe que vous avez, mais je ne sais pas ce que vous y faites. Toute aide est la bienvenue!Je n'ai pas assez de réputation pour répondre à la question @Ram S sous @micmdk reply, je vais donc ajouter ma note ici.
Lorsque vous utilisez UITabbarController , essayez de changer self.viewControllers.lastObject dans le code de @ micmdk en self.selectedViewController comme ceci:
la source
Vous pouvez implémenter et remplacer shouldAutorotate () et supportedInterfaceOrientations var dans toutes vos classes View Controller qui doivent être présentées dans des orientations différentes de celles définies dans PLIST de votre application.
Cependant, dans une interface utilisateur non triviale, vous pourriez rencontrer un problème pour l'ajouter dans des dizaines de classes et vous ne voulez pas les faire toutes sous-classes de plusieurs communes qui le prennent en charge (MyBaseTableViewController, MyBaseNavigationController et MyBaseTabBarController).
Étant donné que vous ne pouvez pas remplacer directement ces method / var sur UIViewController, vous pouvez le faire sur ses sous-classes qui sont généralement des classes de base comme UITableViewController, UINavigationController et UITabBarController.
Vous pouvez donc implémenter quelques extensions et toujours configurer MyPreciousViewController pour qu'il s'affiche dans des orientations différentes de celles de tous les autres, comme cet extrait de code Swift 4:
la source
J'ai résolu le même genre de problème.
Si vous utilisez
UINavigationController
pour pousser les contrôleurs de vue, vous devez définir les méthodes ci-dessous.À la place de l'
LoginViewController
utilisation queUIViewController
vous voulez montrer. Dans mon cas, je veux afficher leLoginViewController
dans lePortrait
mode autreViewControllers
enlandscape
mode.la source
Veuillez utiliser la méthode suivante pour résoudre ce problème
ne retournez que l'orientation que vous souhaitez !!!
la source