web-dev-qa-db-fra.com

Déterminer UIInterfaceOrientation sur iPad

Je n'ai pas besoin de spécifier l'orientation dans ce cas, j'ai juste besoin de la détecter, mais j'ai des problèmes. J'ai un code conditionnel qui ne devrait fonctionner qu'en mode portrait, et si l'appareil est en mode paysage, je dois faire autre chose. Puisque deviceOrientation n'est pas nécessairement identique à interfaceOrientation, je ne peux pas trouver de moyen de tester le mode portrait.

La plupart des didacticiels que je trouve sur Google sont des moyens de forcer la création de paysages ou d'effectuer une sorte de rotation. La seule chose que je veux faire, c'est simplement déterminer l'orientation. Voici mon code, qui ne fonctionne pas:

-(void)viewDidLoad {
    [super viewDidLoad];
    //currentOrientation is declared as UIInterfaceOrientation currentOrientation
    currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
NSLog(@"%@",currentOrientation);  // == NULL
}

Je dois déterminer la valeur de l'interfaceOrientation et du programme conditionnellement. Merci de votre aide!

34
Justin

Êtes-vous au courant de la propriété interfaceOrientation de la classe UIViewController?

- (void) viewDidLoad {
    [super viewDidLoad];
    BOOL isPortrait = UIDeviceOrientationIsPortrait(self.interfaceOrientation);
    // now do whatever you need
}

Ou êtes-vous après [[UIDevice currentDevice] orientation] ?

78
zoul

En particulier lors du lancement, j’ai trouvé que les éléments suivants étaient toujours exacts pour l’UI, quelle que soit la signification donnée par UIDevice.

[UIApplication sharedApplication].statusBarOrientation
39
slycrel

self.interfaceOrientation n'est pas fiable dans certaines situations. Par exemple, la réorganisation des onglets dans une application à barre de tabulation renvoie une valeur incorrecte.

Cependant, [UIApplication sharedApplication].statusBarOrientation est toujours fiable. Tu m'as économisé beaucoup de temps slycrel. Je vous remercie.

10
Devang Vyas
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

if ((orientation == UIInterfaceOrientationLandscapeLeft)
||  (orientation == UIInterfaceOrientationLandscapeRight) )
{
    //Landscape
}
else
{
    //Portrait
}
4
Akshay Dhavale

J'ai déjà voté la réponse par @slycrel, mais je voudrais prendre le temps de l'écrire et de souligner certaines choses qui semblent être perdues dans cette vieille question, ainsi que de nombreuses autres questions sur le sujet.

Il est vrai qu'Apple ne veut pas vraiment que nous mettions à jour la plupart de notre interface utilisateur en fonction des changements d'orientation, mais cela reste tout à fait possible et parfois nécessaire au cas par cas, et ce sera le cas jusqu'à ce qu'Apple améliore sa nouvelle (ish) API (par exemple, viewWillTransitionToFrame: serait bien plus utile que viewWillTransitionToSize:. Just sayin ')

Pourquoi j'ai voté, la réponse de @slycrel est liée à ce que vous devez garder à l'esprit comme différence logique entre UIDeviceOrientation et UIInterfaceOrientation.

La barre d'état indique ce qui est actuellement connu d'une application UIInterfaceOrientation. Tous ces éléments sur FaceUp, FaceDown sont uniquement liés à l'orientation du périphérique, pas nécessairement à celle de votre application. Une application ne supporte de toute façon pas les orientations des appareils . Vraiment, UIDeviceOrientation peut être complètement ignoré si tout ce que vous avez à faire est de vous assurer de disposer et d'animer correctement les éléments de votre interface, ce qui représente 99% des cas d'utilisation d'un développeur d'application. Ceci est actuellement réalisé avec la réponse de la barre d'état UIInterfaceOrientation from @ slycrel: 

[UIApplication sharedApplication].statusBarOrientation

Il convient de noter que la version readwrite de cette propriété est obsolète, tandis que la version readonly n'est pas.

Prenons cet exemple:

  • J'ai une application qui prend en charge TOUTES les orientations d'interface et un contrôleur de vue racine qui les prend également en charge.
  • Maintenant, je présente un UIViewController qui aura pour effet de transformer l'orientation de la barre d'état en paysage.
  • L'orientation paysage (gauche ou droite) à laquelle il se rapporte est basée sur ce qui est retourné par preferredInterfaceOrientationForPresentation pour ce contrôleur de vue, sur l'orientation du périphérique actuel et sur les orientations d'interface prises en charge par le contrôleur de vue (voir point suivant).
  • La barre d'état passe en mode paysage, quelle que soit l'orientation actuelle du périphérique, car ce contrôleur de vue ne prend en charge que le mode paysage en fonction de ce qui est retourné par supportedInterfaceOrientations. Disons que nous soutenons les paysages à gauche et à droite avec UIInterfaceOrientationMaskLandscape.
  • Je souhaite également animer conditionnellement ce contrôleur de vue en position avec une transformation de rotation . Cela ne sera nécessaire que si vous passez de portrait ou portrait à l'envers, paysage à gauche ou paysage à droite. Sinon, ce sera une animation de présentation plus simple sans rotation.
  • Puis, après un certain temps et une utilisation d’appareil, je rejette ce contrôleur de vue.
  • Je souhaite maintenant conditionnellement animer ce contrôleur de vue hors de l’écran avec une autre transformation de rotation . Cela ne sera nécessaire que lorsque vous passerez d'un paysage à gauche ou d'un paysage à droite à un portrait ou un portrait à l'envers. Sinon, ce sera une animation de renvoi plus simple sans rotation.
  • À ce stade, l'orientation de la barre d'état devient celle que le système juge appropriée pour la combinaison de l'orientation préférée de l'interface de votre contrôleur de vue racine et des orientations d'interface prises en charge, ainsi que de la valeur UIDeviceOrientation actuelle du périphérique.
  • Étant donné que le contrôleur de vue que nous allons utiliser prend en charge TOUTES les orientations d'interface, si l'orientation de votre appareil est FaceUp ou FaceDown, vous ne pouvez pas deviner de manière fiable le prochain UIInterfaceOrientation basé sur UIDeviceOrientation, et vous n'êtes pas obligé de le faire.
  • Alors ... orientation de la barre d'état à la rescousse!

L'exemple précédent est possible car l'orientation de la barre d'état n'est pas mise à jour lorsqu'une transition du contrôleur de vue est sur le point de démarrer (le système demande à un délégué de transition de se charger d'un animateur, etc.). Il est ensuite mis à jour lorsque la transition commence l’animation (par exemple, au moment où animationTransition: est appelé). De cette manière, vous devriez avoir une bonne comparaison en utilisant simplement les valeurs initiales et actuelles de la variable UIInterfaceOrientation de la barre d'état.

Même sans utiliser les transitions de contrôleur de vue, il devrait toujours être sûr de mettre à jour les vues en fonction de l'orientation de la barre d'état.

Gardez à l'esprit , si vous mettez à jour manuellement la barre d'état et si vous n'utilisez pas "Afficher l'apparence de la barre d'état basée sur le contrôleur" dans votre Info.plist, la logique de votre application doit être avertie du moment où la barre d'état et a changé d'orientation. Vous chercherez probablement deux noms NSNotification pour ces cas, qui sont:

  • UIApplicationWillChangeStatusBarOrientationNotification
  • UIApplicationDidChangeStatusBarOrientationNotification

En plus de ces méthodes UIApplicationDelegate:

- (void)application:(UIApplication *)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientation duration:(NSTimeInterval)duration;
- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation;
- (UIInterfaceOrientationMask)supportedInterfaceOrientationsForWindow:(nullable UIWindow *)window

Et cette autre propriété utile UIApplication:

@property(nonatomic,readonly) NSTimeInterval statusBarOrientationAnimationDuration;
1
drkibitz
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{</br>
   if (UIDeviceOrientationIsLandscape(toInterfaceOrientation)) {</br>
        some instructions;
   } else { 
        some instructions;
   }
}

C’est un extrait de l’un de mes programmes . Vous pouvez également utiliser l’instruction if dans votre notification ViewDidLoad.

1
crash

Mélangez-le un peu:

BOOL isLandscape = self.view.frame.size.width > self.view.frame.size.height;

(modifier) ​​Évidemment, les réponses précédentes sont la manière correcte de procéder. Cette solution échouerait si les contrôleurs de vue ne sont pas en plein écran.

1
Adam Eisfeld

Je sais que c'est un très vieux post. Cependant, j'aimerais ajouter un point pour dire qu'il est préférable de vérifier que l'orientation de la barre d'état est meilleure. Chaque fois que vous appelez self.interfaceorientation, il appelle shouldRotateToOrientation à chaque fois. Si vous avez écrit du code dans cette méthode, il sera exécuté. Alors soyez prudent!.

1
Vignesh
    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
    UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation; 

    if(deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown){
        if(debug){
            NSLog(@"Nothing to change because it is gone to Flat");
        }
        return;
    }
    if(deviceOrientation !=statusBarOrientation){
        if(debug){
            NSLog(@"\nApple has a bug?:\n UIDeviceOrientation : %d, UIInterfaceOrientation: %d",deviceOrientation, statusBarOrientation  );
        }
    }

Vous ne me croirez pas jusqu'à ce que vous voyiez sur la console la deuxième sortie! Certaines situations - et elles existent! - est affiché le dernier contenu NSLog!

Alors vous devez faire quelques solutions pour continuer sur cette voie, où iOS n’a pas de bogue, bonne chance pour tout le monde!

Ah ça ... le modérateur du forum supprimera peut-être aussi ce post, parce que cela n’est pas censé être et répond à son avis!

J'espère que ça aide pour quelqu'un une fois, ça arrive aussi sur iphone ... (là j'ai compris)

1
user529543

Depuis iOS8, les API sont obsolètes ou renvoient des résultats inutiles tels que .FaceUp.FaceDown

En effet, Apple ne veut PAS que vous mettiez à jour votre interface utilisateur en utilisant l'orientation, mais plutôt en utilisant des classes de taille, des contraintes et des proportions (en utilisant n% de superview).

En effet, le code dépendant de l'orientation peut ne pas donner de bons résultats sur toute la gamme de périphériques et de cas d'utilisation (en particulier le multitâche).

0
Antzi