Gestion des rotations sous iOS 6

muqaddarmuqaddar Administrateur
septembre 2012 modifié dans API UIKit #1
Salut,



Je commence un petit sujet sur les rotations sous iOS 6.



Voilà  ce que j'ai compris.



L'application est par défaut bridée aux interfaces supportées dans votre target. Cela n'a pas bougé sous iOS 6.



Dans cet exemple, on autorise Landscape Left et Landscape Right.



- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)w




Ainsi on peut retourner des rotations en plus que ce qui est précisé dans la target. Par exemple ici, on ajoute le portrait aux 2 modes récupérés depuis le target:


- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)w<br />
{<br />
  return (NSUInteger)[application supportedInterfaceOrientationsForWindow:w] | (1&lt;&lt;UIInterfaceOrientationPortrait);<br />
}




Quel intérêt me direz-vous puisqu'on pourrait ajouter le mode portrait directement dans la target ? Et bien si on autorisait le Portrait dans la target, il faudrait aussi un écran de lancement adapté au mode Portrait... alors que là , il n'est pas nécessaire. Au moment du lancement, seuls le mode Landscape est encore utilisé, pas encore le mode portrait.



Maintenant, que le mode Portrait est autorisé dans toute l'application (ce qui est par exemple obligatoire pour afficher un UIImagePickerController et afficher la librairie photo sous iOS 6), il faut brider les autres vues au mode Landscape uniquement.



Sous iOS <= 5.x, on avait:


// &lt;= iOS 5.x<br />
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation<br />
{<br />
   return UIInterfaceOrientationIsLandscape(interfaceOrientation);<br />
}




Désormais sous iOS 6, il y a 2 méthodes, et les noms des constantes on changé:


// &gt;= iOS 6.x<br />
- (BOOL)shouldAutorotate<br />
{<br />
  return YES;<br />
}<br />
<br />
- (NSUInteger)supportedInterfaceOrientations<br />
{<br />
   return UIInterfaceOrientationMaskLandscape;<br />
}<br />




Voilà  pour mes premiers retours sur la rotation.

Réponses

  • Merci.



    Je m'y pencherai lors de ma première soumission avec Xcode 4.5, puisque la compatibilité semble conservée dès que l'on utilise une version 4.3/4.4.
  • Merci ... je viens de mettre ça en place et ça fonctionne nickel. Comme je suis en portrait j'ai modifié la méthode :


    <br />
    - (NSUInteger)supportedInterfaceOrientations<br />
    {<br />
        return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;<br />
    }<br />
    




    Il faut laisser les anciennes méthodes pour une compatibilité IOS 5.x ?

    J'ai pas encore téléchargé IOS 5.1 simulateur donc je ne peux pas tester.



    A+



    A+
  • Cool, je me demandais pourquoi l'affichage ne fonctionnait pas sur mon simulateur ce matin.

    Merci pour l'ouverture du sujet, je regarde ça ce soir !!!



    [La grande classe ce forum image/smile.png' class='bbc_emoticon' alt=':)' /> ].
  • Ne pas oublier que le rootViewController ne doit pas être nul.
  • ça marche parfaitement !! Nickel. Merci pour l'info.



    K.
  • ThibautThibaut Membre
    septembre 2012 modifié #7
    Comment faire avec un navigationController ?



    J'ai réimplémenté les méthodes suivantes, mais lors d'un pop, une vue autorisée en portrait seulement se retrouve en landscape.


    <br />
    - (BOOL)shouldAutorotate<br />
    {<br />
    	return [self.visibleViewController shouldAutorotate];<br />
    }<br />
    - (NSUInteger)supportedInterfaceOrientations<br />
    {<br />
    	return [self.visibleViewController supportedInterfaceOrientations];<br />
    }<br />
    




    Edit : j'ai rajouter un projet pour tester.

  • J'ai testé ton projet vite fait et effectivement c'est étrange comme comportement.

    Ce qui est encore plus étrange c'est que si tu remplace self.visibleViewController par self.topViewController pour le forward des messages dans ton customNavigationController ça fonctionne parfaitement !
  • Et mince, j'avais déjà  eu ce genre de problèmes. Le visibleViewController est de type "UISnapshotModalViewController" lors des transitions. Il faut donc utiliser topViewController.



    Merci !
  • Bonjour a tous



    J'ai un problème avec une application quoi doit être compatible iOS 5 et 6.

    La rotation du VC dépend des données affiché.



    J'avais le code suivant qui ne posait pas de souci jusqu'à  iOS6 (logique)
    <br />
    [font=Menlo][size=2]<br />
    - ([color=#c800a7]BOOL[/color])shouldAutorotateToInterfaceOrientation:([color=#7b1caf]UIInterfaceOrientation[/color])interfaceOrientation {[/size][/font][font=Menlo][size=2]<br />
    [color=#c800a7]if[/color] ((interfaceOrientation==[color=#470086]UIInterfaceOrientationPortrait[/color]) &amp;&amp; [color=#448388]isForcedLandscape[/color]) [color=#c800a7]return[/color] [color=#c800a7]NO[/color];[/size][/font][color=#470086][font=Menlo][size=2]<br />
    [color=#c800a7]if[/color][color=#000000] ((interfaceOrientation==[/color]UIInterfaceOrientationPortraitUpsideDown[color=#000000]) &amp;&amp; [/color][color=#448388]isForcedLandscape[/color][color=#000000]) [/color][color=#c800a7]return[/color][color=#000000] [/color][color=#c800a7]NO[/color][color=#000000];[/color][/size][/font][/color][font=Menlo][size=2]<br />
    [color=#c800a7]if[/color] ((interfaceOrientation==[color=#470086]UIInterfaceOrientationLandscapeLeft[/color]) &amp;&amp; [color=#448388]isForcedPortrait[/color]) [color=#c800a7]return[/color] [color=#c800a7]NO[/color];[/size][/font][color=#470086][font=Menlo][size=2]<br />
    [color=#c800a7]if[/color][color=#000000] ((interfaceOrientation==[/color]UIInterfaceOrientationLandscapeRight[color=#000000]) &amp;&amp; [/color][color=#448388]isForcedPortrait[/color][color=#000000]) [/color][color=#c800a7]return[/color][color=#000000] [/color][color=#c800a7]NO[/color][color=#000000];[/color][/size][/font][/color]<br />
    [color=#008C00][font=Menlo][size=2]<br />
    [color=#000000]    [/color]// Return YES for supported orientations.[/size][/font][/color][color=#C800A7][font=Menlo][size=2]<br />
    [color=#000000]    [/color]return[color=#000000] [/color]YES[color=#000000];[/color][/size][/font][/color][font=Menlo][size=2]<br />
    }[/size][/font]<br />
    <br />
    




    j'ai donc remplacer par le code compatible iOS6 :
    <br />
    [font=Menlo][size=2]<br />
    - ([color=#c800a7]BOOL[/color]) shouldAutorotate {[/size][/font][color=#C800A7][font=Menlo][size=2]<br />
    [color=#000000]    [/color]return[color=#000000] [/color]YES[color=#000000];[/color][/size][/font][/color][font=Menlo][size=2]<br />
    }[/size][/font]<br />
    [font=Menlo][size=2]<br />
    - ([color=#7b1caf]NSUInteger[/color]) supportedInterfaceOrientations {[/size][/font][color=#448388][font=Menlo][size=2]<br />
    [color=#000000]    [/color][color=#c800a7]if[/color][color=#000000] ([/color]isForcedLandscape[color=#000000]) {[/color][/size][/font][/color][color=#470086][font=Menlo][size=2]<br />
    [color=#000000]        [/color][color=#c800a7]return[/color][color=#000000] [/color]UIInterfaceOrientationMaskLandscape[color=#000000];[/color][/size][/font][/color][font=Menlo][size=2]<br />
        }[/size][/font][color=#448388][font=Menlo][size=2]<br />
    [color=#000000]    [/color][color=#c800a7]if[/color][color=#000000] ([/color]isForcedPortrait[color=#000000]) {[/color][/size][/font][/color][color=#470086][font=Menlo][size=2]<br />
    [color=#000000]        [/color][color=#c800a7]return[/color][color=#000000] [/color]UIInterfaceOrientationMaskPortrait[color=#000000];[/color][/size][/font][/color][font=Menlo][size=2]<br />
        }[/size][/font][color=#470086][font=Menlo][size=2]<br />
    [color=#000000]    [/color][color=#c800a7]return[/color][color=#000000] [/color]UIInterfaceOrientationMaskAll[color=#000000];[/color][/size][/font][/color][font=Menlo][size=2]<br />
    }[/size][/font]<br />
    




    et la Rognntudjuu ! La rotation ne fonctionne plus sur iOS 5...



    Comment faire un code propre compatible ancienne et nouvelle version ?

    Faut-il codé les trois fonction ensemble dans la même classe ?
  • CéroceCéroce Membre, Modérateur
    Ne remplace pas. Laisse l'ancienne méthode en plus de la nouvelle.
  • dream hopedream hope Membre
    octobre 2012 modifié #12
    'Céroce' a écrit:


    Ne remplace pas. Laisse l'ancienne méthode en plus de la nouvelle.






    Comme ça ?
    <br />
    <br />
    [font=Menlo][size=2]- ([color=#c800a7]BOOL[/color])shouldAutorotateToInterfaceOrientation:([color=#7b1caf]UIInterfaceOrientation[/color])interfaceOrientation {[/size][/font]<br />
    [font=Menlo][size=2][color=#c800a7]if[/color] ((interfaceOrientation==[color=#470086]UIInterfaceOrientationPortrait[/color]) &amp;&amp; [color=#448388]isForcedLandscape[/color]) [color=#c800a7]return[/color] [color=#c800a7]NO[/color];[/size][/font]<br />
    [color=#470086][font=Menlo][size=2][color=#c800a7]if[/color][color=#000000] ((interfaceOrientation==[/color]UIInterfaceOrientationPortraitUpsideDown[color=#000000]) &amp;&amp; [/color][color=#448388]isForcedLandscape[/color][color=#000000]) [/color][color=#c800a7]return[/color][color=#000000] [/color][color=#c800a7]NO[/color][color=#000000];[/color][/size][/font][/color]<br />
    [font=Menlo][size=2][color=#c800a7]if[/color] ((interfaceOrientation==[color=#470086]UIInterfaceOrientationLandscapeLeft[/color]) &amp;&amp; [color=#448388]isForcedPortrait[/color]) [color=#c800a7]return[/color] [color=#c800a7]NO[/color];[/size][/font]<br />
    [color=#470086][font=Menlo][size=2][color=#c800a7]if[/color][color=#000000] ((interfaceOrientation==[/color]UIInterfaceOrientationLandscapeRight[color=#000000]) &amp;&amp; [/color][color=#448388]isForcedPortrait[/color][color=#000000]) [/color][color=#c800a7]return[/color][color=#000000] [/color][color=#c800a7]NO[/color][color=#000000];[/color][/size][/font][/color]<br />
    <br />
    [color=#008C00][font=Menlo][size=2][color=#000000]	[/color]// Return YES for supported orientations.[/size][/font][/color]<br />
    [color=#C800A7][font=Menlo][size=2][color=#000000]	[/color]return[color=#000000] [/color]YES[color=#000000];[/color][/size][/font][/color]<br />
    [font=Menlo][size=2]}[/size][/font]<br />
    <br />
    [font=Menlo][size=2]- ([color=#c800a7]BOOL[/color]) shouldAutorotate {[/size][/font]<br />
    [color=#C800A7][font=Menlo][size=2][color=#000000]	[/color]return[color=#000000] [/color]YES[color=#000000];[/color][/size][/font][/color]<br />
    [font=Menlo][size=2]}[/size][/font]<br />
    <br />
    [font=Menlo][size=2]- ([color=#7b1caf]NSUInteger[/color]) supportedInterfaceOrientations {[/size][/font]<br />
    [color=#448388][font=Menlo][size=2][color=#000000]	[/color][color=#c800a7]if[/color][color=#000000] ([/color]isForcedLandscape[color=#000000]) {[/color][/size][/font][/color]<br />
    [color=#470086][font=Menlo][size=2][color=#000000]		[/color][color=#c800a7]return[/color][color=#000000] [/color]UIInterfaceOrientationMaskLandscape[color=#000000];[/color][/size][/font][/color]<br />
    [font=Menlo][size=2]	}[/size][/font]<br />
    [color=#448388][font=Menlo][size=2][color=#000000]	[/color][color=#c800a7]if[/color][color=#000000] ([/color]isForcedPortrait[color=#000000]) {[/color][/size][/font][/color]<br />
    [color=#470086][font=Menlo][size=2][color=#000000]		[/color][color=#c800a7]return[/color][color=#000000] [/color]UIInterfaceOrientationMaskPortrait[color=#000000];[/color][/size][/font][/color]<br />
    [font=Menlo][size=2]	}[/size][/font]<br />
    [color=#470086][font=Menlo][size=2][color=#000000]	[/color][color=#c800a7]return[/color][color=#000000] [/color]UIInterfaceOrientationMaskAll[color=#000000];[/color][/size][/font][/color]<br />
    [font=Menlo][size=2]}[/size][/font]<br />
    




    Sincèrement, ça me parait pas propre...

    xcode ne devrait-il pas lui même compiler de manière à  être compatible ios5 ?
  • Bon, ça y est, je m'en suis sortie de mes rotations, voilà  une solution, pour mon cas particulier que je donne ici, même si à  mon avis c'est un petit peu du bricolage... en attendant mieux :



    - mon appli ne fonctionne qu'en mode paysage : sauf pour la caméra.

    - Même spécificité que cité plus haut : rootviewcontroller.

    - Particularités : dans le appDelegate, j'ai créé une variable qui me dit si j'ai le droit de pivoter ou non : je la mets à  YES quand j'active la camera, je la remets à  NO au "dismiss" de la camera.



    - Je teste cette variable dans la méthode "SupportedInterfaceOrientationForWindow".


    <br />
    - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window;<br />
    {<br />
    	if (self.viewCanRotate)<br />
    	{<br />
    		// si je suis en mode camera<br />
    		return (UIInterfaceOrientationAllMask);<br />
    	}<br />
    	else<br />
    	{<br />
    		// si je suis en mode normal, pas de rotation autorisée<br />
    		return (UIInterfaceOrientationLandscapeMask);<br />
    	}<br />
    }<br />
    




    Comme cette méthode est appelée à  chaque rotation, il me renvoie bien la bonne valeur selon ce que je veux à  un moment donné.

    Le différence avec IOS5 est que l'on peut changer par programme les orientations supportées par l'appli.
  • Bonjour,



    J'ai implémenté tout ce qu'il faut pour iOS6 mais ça ne fonctionne pas pour toutes les vues.



    Au démarrage de l'appli, je lance une vue qui permet de sélectionner ses médias, puis après sélection, on peut les lire via un player.





    la 1ère vue est lancée via le AppDelegate -> window.rootViewController = navigationController; en mode portrait



    La vue du player est lancé par un "presentModalViewController" avec un mode paysage.





    La 1ère vue ne respecte pas le portrait, elle pivote des tous les sens.



    Le player quand à  lui est bien en paysage.



    Si je change l'appel de la vue du player en "pushViewController" le player tourne dans tous les sens.



    Avez-vous une idée ?



    Merci.
  • Oui.



    Tu peux déjà  te présenter.



    Ensuite il faut que tu sous-classes UINavigationController et reprenne le post Thibaut un peu plus haut. Normalement tout devrait rouler par la suite.
  • Merci pour la réponse.



    Je suis un développeur débutant en iOS.



    J'ai créée une catégorie avec UiNavigationController en ajoutant les deux nouvelles méthodes et ça fonctionne.



    Merci encore :-).



    ++
  • 'staroun' a écrit:


    Merci pour la réponse.



    Je suis un développeur débutant en iOS.



    J'ai créée une catégorie avec UiNavigationController en ajoutant les deux nouvelles méthodes et ça fonctionne.



    Merci encore :-).



    ++




    C'est une mauvais idée d'utiliser une catégorie pour surcharger ces méthodes sur UINavigationController.

    J'ai écrit un article à  ce sujet.
  • AliGatorAliGator Membre, Modérateur
    +1000 ne jamais utiliser une catégorie pour surcharger une méthode existante !



    Les catégories ne doivent être utilisées exclusivement que pour rajouter des méthodes encore inexistantes à  des classes existantes, surtout pas pour surcharger car comme l'explique Thomas dans son article, non seulement ce n'est pas fait pour et le Runtime n'est pas prévu pour ça, mais on n'a aucune garantie de savoir quelle implémentation prendra le pas sur l'autre.



    Malheureusement, on a vu à  une époque traà®ner sur le net par exemple une "catégorie pour surcharger" le drawRect de UINavigationBar. C'est une très mauvaise idée et une solution sans garantie et posant des soucis, mais malheureusement cette solution a rapidement fait le tour du net (grâce à  twitter et quelques forums qui relayaient sans réfléchir) et a été utilisée à  plusieurs reprises malgré que ce soit une solution incorrecte et fortement déconseillée car inadéquate. J'espère qu'on ne verra pas le même genre d'aberration avec les méthodes pour rajouter la rotation à  UINavigationController, ce serait dommage de rentrer dans le même cycle de désinformation et de populariser une solution incorrecte et dangereuse...
Connectez-vous ou Inscrivez-vous pour répondre.