97 votes

Comment obtenir l’orientation dépendant hauteur et la largeur de l’écran ?

Je suis en train de déterminer par programme la hauteur actuelle et la largeur de mon application. J’utilise ceci :

Mais cela donne une largeur de 320 et une hauteur de 480, indépendamment de savoir si l’appareil est en mode portrait ou paysage. Comment puis-je déterminer l’actuelle largeur et la hauteur (c'est-à-dire dépendante de l’orientation de l’appareil) de mon écran principal ?

164voto

Sam Points 13570

Vous pouvez utiliser quelque chose comme UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) pour déterminer l'orientation et ensuite utiliser les dimensions en conséquence.

CEPENDANT, lors d'un changement d'orientation comme dans UIViewController de l'

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
                                 duration:(NSTimeInterval)duration

L'utilisation de l'orientation adoptée en toInterfaceOrientation depuis le UIApplication de statusBarOrientation sera pointent toujours vers l'ancien orientation, car il n'a pas encore changé (puisque vous êtes à l'intérieur d'un will gestionnaire d'événement).

Résumé

Il y a plusieurs postes liés à cela, mais chacun d'entre eux semblent indiquer que vous avez à:

  1. Regardez - [[UIScreen mainScreen] bounds] pour obtenir les dimensions,
  2. Vérifiez que l'orientation que vous êtes, et
  3. Compte pour la barre d'état de la hauteur (si indiqué)

Liens

Code De Travail

J'ai l'habitude de ne pas aller aussi loin, mais vous a piqué mon intérêt. Le code suivant devrait faire l'affaire. J'ai écrit une Catégorie sur UIApplication. J'ai ajouté les méthodes de la classe pour obtenir le currentSize ou la taille dans une orientation, qui est ce que vous appelez dans UIViewController de l' willRotateToInterfaceOrientation:duration:.

@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end

@implementation UIApplication (AppDimensions)

+(CGSize) currentSize
{
    return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
    CGSize size = [UIScreen mainScreen].bounds.size;
    UIApplication *application = [UIApplication sharedApplication];
    if (UIInterfaceOrientationIsLandscape(orientation))
    {
        size = CGSizeMake(size.height, size.width);
    }
    if (application.statusBarHidden == NO)
    {
        size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
    }
    return size;
}

@end

Pour utiliser le code simple appel [UIApplication currentSize]. Aussi, j'ai couru le code ci-dessus, donc je sais que ça fonctionne et rapporte les réponses correctes dans toutes les orientations. Notez que le facteur I dans la barre d'état. Il est intéressant de noter que j'avais pour soustraire le MIN de la barre d'état de la hauteur et de la largeur.

Espérons que cette aide. :D

D'autres pensées

Vous pourriez obtenir les dimensions en regardant le UIWindow de l' rootViewController de la propriété. J'ai regardé dans le passé et de la même manière les rapports les mêmes dimensions à la fois portrait et paysage à l'exception des rapports d'avoir une rotation de transformation:

(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController]]

<UILayoutContainerView: 0xf7296f0; frame = (0 0; 320 480); transformation = [0, -1, 1, 0, 0, 0]; autoresize = W+H; couche = <CALayer: 0xf729b80>>

(gdb) po [[[[UIApplication sharedApplication] keyWindow] rootViewController]]

<UILayoutContainerView: 0xf7296f0; frame = (0 0; 320 480); autoresize = W+H; couche = <CALayer: 0xf729b80>>

Vous ne savez pas comment votre application fonctionne, mais si vous n'êtes pas à l'aide d'une manette de navigation d'un certain type, vous pourriez avoir une UIView sous votre vue principale avec le max de hauteur / largeur de parent et augmente / réduit avec les parents. Alors que vous pourriez faire: [[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame]. Cela semble assez intense sur une seule ligne, mais vous obtenez l'idée.

Cependant... Il serait encore mieux de le faire au-dessus de 3 étapes dans le résumé. Commencer à jouer avec UIWindows et vous verrez des choses bizarres, comme montrer une UIAlertView va changer UIApplication de keywindow au point un nouveau UIWindow que le UIAlertView créé. Qui le savait? Je l'ai fait après avoir trouvé un bug en s'appuyant sur keyWindow et de découvrir que il a changé comme ça!

39voto

Monjer Points 329

C'est ma solution de code !Cette méthode peut ajouter à la classe NSObject de la Catégorie , ou vous pouvez définir un Top personnalisé UIViewController classe , et laissez tous vos autres UIViewControllers d'en hériter .

-(CGRect)currentScreenBoundsDependOnOrientation
{  

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
    }
    return screenBounds ;
}

Remarque, après IOS8 , Apple Document de UIScreen de la propriété bounds dit :

Discussion

Ce rectangle est spécifiée dans l'espace de coordonnées, qui prend en compte toute l'interface de rotations en effet du périphérique. Par conséquent, la valeur de cette propriété peut changer lorsque l'appareil tourne entre les orientations portrait et paysage.

donc, pour l'examen de la compatibilité , nous devons détecter la version d'IOS et d'apporter une modification comme ci-dessous:

#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)

-(CGRect)currentScreenBoundsDependOnOrientation
{  

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    if(IsIOS8){
        return screenBounds ;
    }
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
    }
    return screenBounds ;
}

31voto

Robert Wagstaff Points 978

Voici une macro pratique:

 #define SCREEN_WIDTH ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)
#define SCREEN_HEIGHT ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)
 

10voto

Rich Able Points 566

Depuis iOS 8, les limites de l'écran sont maintenant renvoyées correctement pour l'orientation actuelle. Cela signifie qu'un iPad en orientation paysage [UIScreen mainScreen] .bounds renverra 768 sur iOS <= 7 et 1024 sur iOS 8.

Ce qui suit renvoie la hauteur et la largeur correctes pour toutes les versions publiées.

 -(CGRect)currentScreenBoundsDependOnOrientation
{
    NSString *reqSysVer = @"8.0";
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
        return [UIScreen mainScreen].bounds;

    CGRect screenBounds = [UIScreen mainScreen].bounds ;
    CGFloat width = CGRectGetWidth(screenBounds)  ;
    CGFloat height = CGRectGetHeight(screenBounds) ;
    UIInterfaceOrientation interfaceOrientation = [UIApplication sharedApplication].statusBarOrientation;

    if(UIInterfaceOrientationIsPortrait(interfaceOrientation)){
        screenBounds.size = CGSizeMake(width, height);
        NSLog(@"Portrait Height: %f", screenBounds.size.height);
    }else if(UIInterfaceOrientationIsLandscape(interfaceOrientation)){
        screenBounds.size = CGSizeMake(height, width);
        NSLog(@"Landscape Height: %f", screenBounds.size.height);
    }

    return screenBounds ;
}
 

8voto

Tod Points 1798

si vous voulez la taille dépendant de l'orientation et que vous avez une vue, vous pouvez simplement utiliser:

 view.bounds.size
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X