Comment obtenir la largeur et la hauteur de l'écran dans iOS?

506

Comment obtenir les dimensions de l'écran dans iOS?

Actuellement, j'utilise:

lCurrentWidth = self.view.frame.size.width;
lCurrentHeight = self.view.frame.size.height;

dans viewWillAppear:etwillAnimateRotationToInterfaceOrientation:duration:

La première fois que j'obtiens toute la taille de l'écran. La deuxième fois, je reçois l'écran moins la barre de navigation.

griotspeak
la source

Réponses:

1063

Comment obtenir les dimensions de l'écran dans iOS?

Le problème avec le code que vous avez publié est que vous comptez sur la taille de la vue pour correspondre à celle de l'écran, et comme vous l'avez vu, ce n'est pas toujours le cas. Si vous avez besoin de la taille de l'écran, vous devez regarder l'objet qui représente l'écran lui-même, comme ceci:

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;

Mise à jour pour la vue partagée: Dans les commentaires, Dmitry a demandé:

Comment obtenir la taille de l'écran dans la vue fractionnée?

Le code donné ci-dessus indique la taille de l'écran, même en mode écran partagé. Lorsque vous utilisez le mode écran partagé, la fenêtre de votre application change. Si le code ci-dessus ne vous donne pas les informations que vous attendez, alors comme l'OP, vous regardez le mauvais objet. Dans ce cas, cependant, vous devriez regarder la fenêtre au lieu de l'écran, comme ceci:

CGRect windowRect = self.view.window.frame;
CGFloat windowWidth = windowRect.size.width;
CGFloat windowHeight = windowRect.size.height;

Swift 4.2

let screenRect = UIScreen.main.bounds
let screenWidth = screenRect.size.width
let screenHeight = screenRect.size.height

// split screen            
let windowRect = self.view.window?.frame
let windowWidth = windowRect?.size.width
let windowHeight = windowRect?.size.height
Caleb
la source
7
L'orientation est vraiment gérée au niveau du contrôleur de vue. Jetez un œil à la gestion de l'orientation de l'interface d'un contrôleur de vue . Alors oui, regardez la propriété interfaceOrientation de votre contrôleur de vue. BTW, vous avez posé des questions sur la taille de l'écran, c'est donc ce que je vous ai montré, mais pour afficher votre contenu, vous devriez probablement utiliser les limites de la fenêtre ou le cadre d'application de l'écran, selon ce que vous faites.
Caleb
2
il est utile de noter que cela renvoie la pleine largeur de l'écran sans remplissage. Soustrayez simplement le remplissage de votre application (généralement 20 de chaque côté) de ces résultats pour obtenir l'espace `` utilisable '' pour la plupart des éléments
Nick Daugherty
2
@NickDaugherty Oui, c'est le point - l'OP voulait les dimensions de l'écran. L'endroit où vous placez des objets à l'écran dépend entièrement de vous et dépend du type d'application que vous créez. Si vous affichez une photo ou une interface de jeu, par exemple, vous ne voudrez peut-être pas du tout de rembourrage.
Caleb
3
Notez cependant que cela renvoie une valeur mesurée en points. Donc, si vous vous attendiez à la résolution d'écran en pixels, le résultat serait incorrect et vous devriez multiplier le résultat par [UIScreen scale].
Robotbugs
3
Quelqu'un a fait remarquer qu'un CGRect pouvant avoir une largeur ou une hauteur négative , nous devrions utiliser CGRectGetWidth()et CGRectGetHeight()au lieu d'accéder directement au sizechamp dans le rectangle. Je ne pense pas que ce soit un problème avec le rectangle d'écran, mais je suppose que c'est quelque chose dont il faut être conscient.
Caleb
64

Attention, [UIScreen mainScreen] contient également une barre d'état, si vous souhaitez récupérer le cadre de votre application (à l'exclusion de la barre d'état), vous devez utiliser

+ (CGFloat) window_height   {
    return [UIScreen mainScreen].applicationFrame.size.height;
}

+ (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}
Ege Akpinar
la source
4
obsolète dans iOS 9.0
Zakaria Darwish
6
depuis applicationFrame est obsolète, remplacez parreturn [[UIScreen mainScreen] bounds].size.width;
lizzy81
44

J'ai traduit certaines des réponses Objective-C ci-dessus en code Swift. Chaque traduction est effectuée avec une référence à la réponse originale.

Réponse principale

let screen = UIScreen.main.bounds
let screenWidth = screen.size.width
let screenHeight = screen.size.height

Réponse de fonction simple

func windowHeight() -> CGFloat {
    return UIScreen.mainScreen().applicationFrame.size.height
}

func windowWidth() -> CGFloat {
    return UIScreen.mainScreen().applicationFrame.size.width
}

Réponse d'orientation de l'appareil

var screenHeight : CGFloat
let statusBarOrientation = UIApplication.sharedApplication().statusBarOrientation
// it is important to do this after presentModalViewController:animated:
if (statusBarOrientation != UIInterfaceOrientation.Portrait
    && statusBarOrientation != UIInterfaceOrientation.PortraitUpsideDown){
    screenHeight = UIScreen.mainScreen().applicationFrame.size.width
} else {
    screenHeight = UIScreen.mainScreen().applicationFrame.size.height
}

Journal réponse

let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
println("width: \(screenWidth)")
println("height: \(screenHeight)")
Martin Woolstenhulme
la source
Il semble qu'il y ait une faute de frappe dans la réponse du journal: devrait-il s'agir de UIScreen.mainScreen (). Bounds.size.width? J'obtiens une erreur de compilation sans les ".bounds".
pierre
@skypecakes J'ai corrigé la réponse pour inclure ".bounds". Merci pour les commentaires.
Martin Woolstenhulme
applicationFrame est déconseillé dans iOS 9 et supérieur, remplacez parreturn UIScreen.mainScreen().bounds].size.width
Suhaib
39

J'ai déjà utilisé ces méthodes pratiques:

- (CGRect)getScreenFrameForCurrentOrientation {
    return [self getScreenFrameForOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

- (CGRect)getScreenFrameForOrientation:(UIInterfaceOrientation)orientation {

    CGRect fullScreenRect = [[UIScreen mainScreen] bounds];

    // implicitly in Portrait orientation.
    if (UIInterfaceOrientationIsLandscape(orientation)) {
      CGRect temp = CGRectZero;
      temp.size.width = fullScreenRect.size.height;
      temp.size.height = fullScreenRect.size.width;
      fullScreenRect = temp;
    }

    if (![[UIApplication sharedApplication] statusBarHidden]) {
      CGFloat statusBarHeight = 20; // Needs a better solution, FYI statusBarFrame reports wrong in some cases..
      fullScreenRect.size.height -= statusBarHeight;
    }

    return fullScreenRect;
} 
Luke Mcneice
la source
Belle solution, mais attention à ce que la température semble avoir une origine non définie.
szemian
4
Obtenez-vous 0,0 par défaut? Lorsque j'ai enregistré le fullScreenRect, il m'a donné: {{8.03294e-35, 3.09816e-40}, {480, 320}}. J'ai choisi d'initialiser avec CGRect temp = CGRectZero;
szemian
1
UIInterfaceOrientationIsLandscape ne gère pas «UIDeviceOrientationFaceUp» et «UIDeviceOrientationFaceDown» qui peuvent être renvoyés par UIDevice.
Andriy
6
Vous pouvez utiliser la propriété screen.applicationFrame au lieu de screen.bounds qui s'occupe de la barre d'état.
Geraud.ch
Il s'avère que dans certains cas, applicationFrame ne renvoie pas de trame avec une barre d'état correctement soustraite (modaux plein écran d'une vue partagée)
Luke Mcneice
15

Je me rends compte que c'est un ancien article, mais parfois je trouve utile de # définir des constantes comme celles-ci, donc je n'ai pas à m'en soucier:

#define DEVICE_SIZE [[[[UIApplication sharedApplication] keyWindow] rootViewController].view convertRect:[[UIScreen mainScreen] bounds] fromView:nil].size

La constante ci-dessus doit renvoyer la taille correcte quelle que soit l'orientation de l'appareil. Ensuite, obtenir les dimensions est aussi simple que:

lCurrentWidth = DEVICE_SIZE.width;
lCurrentHeight = DEVICE_SIZE.height;
Un utilisateur aléatoire
la source
Vous voudrez peut-être baser la macro sur la réponse de AnswerBot car cela semble être la meilleure réponse.
griotspeak
13

Il est très, très facile d'obtenir la taille de votre appareil et de prendre en compte l'orientation:

// grab the window frame and adjust it for orientation
UIView *rootView = [[[UIApplication sharedApplication] keyWindow] 
                                   rootViewController].view;
CGRect originalFrame = [[UIScreen mainScreen] bounds];
CGRect adjustedFrame = [rootView convertRect:originalFrame fromView:nil];
memmons
la source
Salut, je l'utilise dans viewDidLoad sur une application iPad uniquement en mode paysage, y a-t-il une raison pour laquelle il obtient la bonne valeur la première fois, puis la valeur «bascule» à chaque chargement après que, c'est-à-dire qu'il la lit comme première vue du paysage, puis je revenir en arrière et revenir à la vue et il semble la lire comme portrait même si aucun changement d'orientation n'a été fait? Merci
craigk
@LukeMcneice Dans mon code de production, j'ai une assertion pour m'assurer qu'une trame est trouvée ... Je dois encore faire échouer cette assertion. Qu'est-ce qui est retourné pour rootView et originalFrame?
memmons
J'utilise cette technique dans un singleton pour obtenir la largeur / hauteur corrigée de l'orientation. Cependant, si ce code s'exécute alors qu'une fenêtre UIAlert affichant le convertRect retourne adjustFrame avec une taille (largeur au moins) de 0. Avez-vous des réflexions sur ce qui se passe avec ça?
Electro-Bunny
Ah. An UIAlertViews'insérera en tant que vue rootViewController de keyWindow. J'ai une logique qui évite le cas du coin parce que si une vue d'alerte est en place, l'utilisateur ne peut pas interagir avec le clavier, il n'est donc généralement pas nécessaire de saisir le cadre du clavier à ce moment.
memmons
Merci pour la perspicacité. J'utilisais votre technique dans une bannière publicitaire singleton. C'était une façon simple et agréable d'indiquer à l'API de l'annonce la taille du cadre de l'écran pour une nouvelle annonce. Étant donné que je ne serai pas en mesure d'exclure mutuellement les bannières publicitaires et celles de UIAlert, je recourrai probablement à la détection de paysage par rapport au portrait et à la commutation par force brute x / y si nécessaire.
Electro-Bunny
9

Nous devons également considérer l'orientation de l'appareil:

CGFloat screenHeight;
// it is important to do this after presentModalViewController:animated:
if ([[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIDeviceOrientationPortraitUpsideDown){
    screenHeight = [UIScreen mainScreen].applicationFrame.size.height;
}
else{
    screenHeight = [UIScreen mainScreen].applicationFrame.size.width;
}
Oleh Kudinov
la source
Bonne solution J'ai fait cela pour que mon application iPad fonctionne en paysage depuis l'intérieur d'un contrôleur de vue intégré lors de la présentation d'un VC modal.
StackRunner
8
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.width);
NSLog(@"%.0f", [[UIScreen mainScreen] bounds].size.height);
Gaurav Gilani
la source
5

Ici, j'ai mis à jour pour swift 3

applicationFrame déconseillé d'iOS 9

Dans swift trois, ils ont supprimé () et ils ont changé quelques conventions de dénomination, vous pouvez vous référer ici Lien

func windowHeight() -> CGFloat {
    return UIScreen.main.bounds.size.height
}

func windowWidth() -> CGFloat {
    return UIScreen.main.bounds.size.width
}
karthikeyan
la source
4

La réponse moderne:

si votre application prend en charge la vue fractionnée sur iPad, ce problème devient un peu compliqué. Vous avez besoin de la taille de la fenêtre, pas de celle de l'écran, qui peut contenir 2 applications. La taille de la fenêtre peut également varier lors de l'exécution.

Utilisez la taille de la fenêtre principale de l'application:

UIApplication.shared.delegate?.window??.bounds.size ?? .zero

Remarque: La méthode ci-dessus peut obtenir une valeur incorrecte avant que la fenêtre ne devienne une fenêtre clé au démarrage. si vous avez seulement besoin de largeur, la méthode ci-dessous est très recommandée :

UIApplication.shared.statusBarFrame.width

L'ancienne solution utilisant UIScreen.main.boundsretournera les limites de l'appareil. Si votre application s'exécute en mode d'affichage fractionné, elle obtient les mauvaises dimensions.

self.view.window dans la réponse la plus chaude, la taille peut être incorrecte lorsque l'application contient 2 fenêtres ou plus et que la fenêtre est de petite taille.

leavez
la source
4

Utilisez-les Structspour connaître des informations utiles sur le périphérique actuel dans Swift 3.0

struct ScreenSize { // Answer to OP's question

    static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
    static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
    static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
    static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)

}

struct DeviceType { //Use this to check what is the device kind you're working with

    static let IS_IPHONE_4_OR_LESS  = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
    static let IS_IPHONE_SE         = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
    static let IS_IPHONE_7          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 667.0
    static let IS_IPHONE_7PLUS      = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
    static let IS_IPHONE_X          = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812.0
    static let IS_IPAD              = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0

}


struct iOSVersion { //Get current device's iOS version

    static let SYS_VERSION_FLOAT  = (UIDevice.current.systemVersion as NSString).floatValue
    static let iOS7               = (iOSVersion.SYS_VERSION_FLOAT >= 7.0 && iOSVersion.SYS_VERSION_FLOAT < 8.0)
    static let iOS8               = (iOSVersion.SYS_VERSION_FLOAT >= 8.0 && iOSVersion.SYS_VERSION_FLOAT < 9.0)
    static let iOS9               = (iOSVersion.SYS_VERSION_FLOAT >= 9.0 && iOSVersion.SYS_VERSION_FLOAT < 10.0)
    static let iOS10              = (iOSVersion.SYS_VERSION_FLOAT >= 10.0 && iOSVersion.SYS_VERSION_FLOAT < 11.0)
    static let iOS11              = (iOSVersion.SYS_VERSION_FLOAT >= 11.0 && iOSVersion.SYS_VERSION_FLOAT < 12.0)
    static let iOS12              = (iOSVersion.SYS_VERSION_FLOAT >= 12.0 && iOSVersion.SYS_VERSION_FLOAT < 13.0)

}
badhanganesh
la source
3

Si vous souhaitez une largeur / hauteur d'écran quelle que soit l'orientation de l'appareil (idéal pour le dimensionnement portrait uniquement, les contrôleurs de vue sont lancés à partir des orientations paysage):

CGFloat screenWidthInPoints = [UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale;
CGFloat screenHeightInPoints = [UIScreen mainScreen].nativeBounds.size.height/[UIScreen mainScreen].nativeScale;

[UIScreen mainScreen] .nativeBounds <- D'après les documents -> Le rectangle englobant de l'écran physique, mesuré en pixels. Ce rectangle est basé sur l'appareil dans une orientation portrait vers le haut. Cette valeur ne change pas lorsque l'appareil tourne.

John Erck
la source
2

Voici une façon rapide d'obtenir des tailles d'écran:

print(screenWidth)
print(screenHeight)

var screenWidth: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.width
    } else {
        return UIScreen.mainScreen().bounds.size.height
    }
}

var screenHeight: CGFloat {
    if UIInterfaceOrientationIsPortrait(screenOrientation) {
        return UIScreen.mainScreen().bounds.size.height
    } else {
        return UIScreen.mainScreen().bounds.size.width
    }
}

var screenOrientation: UIInterfaceOrientation {
    return UIApplication.sharedApplication().statusBarOrientation
}

Ceux-ci sont inclus en tant que fonction standard dans:

https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
la source
1

CGFloat width = [[UIScreen mainScreen] bounds].size.width; CGFloat height = [[UIScreen mainScreen]bounds ].size.height;

Himanshu jamnani
la source
1

swift 3.0

pour largeur

UIScreen.main.bounds.size.width

pour hauteur

UIScreen.main.bounds.size.height
Amul4608
la source
-2

Vous pouvez placer ces macros dans votre fichier pch et les utiliser n'importe où dans le projet en utilisant "SCREEN_WIDTH"

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

et "SCREEN_HEIGHT"

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

Exemple d'utilisation:

CGSize calCulateSizze ;
calCulateSizze.width = SCREEN_WIDTH/2-8;
calCulateSizze.height = SCREEN_WIDTH/2-8;
Anny
la source
Pouvez-vous mettre en retrait votre code selon le format de démarque? Actuellement, cela a été signalé comme "de faible qualité" par les utilisateurs de la communauté dans la file d'attente de révision.
Manoj Kumar