Comment obtenir par programme la hauteur de la barre d'état iOS

277

Je sais qu'actuellement, la barre d'état (avec l'heure, la batterie et la connexion réseau) en haut de l'iPhone / iPad est de 20 pixels pour les écrans non rétiniens et 40 pixels pour les écrans rétiniens, mais pour pérenniser mon application, je voudrais pour pouvoir le déterminer sans valeurs de codage en dur. Est-il possible de déterminer la hauteur de la barre d'état par programme?

lehn0058
la source

Réponses:

506

[UIApplication sharedApplication].statusBarFrame.size.height. Mais comme toutes les tailles sont en points et non en pixels, la hauteur de la barre d'état est toujours égale à 20.

Mettre à jour. Voyant cette réponse jugée utile, je devrais élaborer.

La hauteur de la barre d'état est en effet égale à 20,0 points, sauf dans les cas suivants:

  • la barre d'état a été masquée avec la setStatusBarHidden:withAnimation:méthode et sa hauteur est égale à 0,0f points;
  • comme @Anton l'a souligné ici, lors d'un appel entrant en dehors de l'application Téléphone ou pendant la hauteur de la barre d'état de la session d'enregistrement sonore est égale à 40,0 points.

Il y a aussi un cas de barre d'état affectant la hauteur de votre vue. Normalement, la hauteur de la vue est égale à la dimension de l'écran pour une orientation donnée moins la hauteur de la barre d'état. Toutefois, si vous animez la barre d' état (afficher ou à masquer) après le point de vue a été montré, la barre d'état changera son cadre, mais la vue ne sera pas , vous devrez redimensionner manuellement la vue après l' animation de la barre d'état (ou pendant l' animation depuis la hauteur de la barre d'état prend la valeur finale au début de l'animation).

Mise à jour 2. Il y a aussi un cas d'orientation de l'interface utilisateur. La barre d'état ne respecte pas la valeur d'orientation, donc la valeur de la hauteur de la barre d'état pour le mode portrait est [UIApplication sharedApplication].statusBarFrame.size.height(oui, l'orientation par défaut est toujours portrait, peu importe ce que dit votre application info.plist), pour le paysage - [UIApplication sharedApplication].statusBarFrame.size.width. Pour déterminer l'orientation actuelle de l'interface utilisateur lorsqu'elle est en dehors de UIViewControlleret self.interfaceOrientationn'est pas disponible, utilisez [UIApplication sharedApplication].statusBarOrientation.

Mise à jour pour iOS7. Même si le style visuel de la barre d'état a changé, il est toujours là, son cadre se comporte toujours de la même manière. La seule découverte intéressante sur la barre d'état je me suis - part I: votre UINavigationBar« s carrelage fond sera également carrelée à la barre d'état, de sorte que vous pouvez obtenir des effets de design intéressant ou tout simplement la couleur de votre barre d'état. Cela n'affectera pas non plus la hauteur de la barre d'état.

L'arrière-plan de la barre de navigation est également affiché dans la barre d'état

Kyr Dunenkoff
la source
6
Cette méthode donne 1024 () iOS 7
Marc
1
@MarcMosby, voir ma mise à jour. Rappelé ce problème - grâce à vous.
Kyr Dunenkoff
2
Oui, comme Marc l'a souligné sur iOS7, il en produit 1024 parfois et 20 parfois. Ce n'est donc plus un moyen infaillible de déterminer la hauteur. Je doute que cela soit dû à la nature transparente de la barre d'état sur iOS 7. Il se pourrait que cela passe d'abord en plein écran, puis se redimensionne. Donc, si vous appliquez des requêtes pendant cette transition, vous risquez d'obtenir la mauvaise valeur. L'appel de cette méthode avec un délai peut aider sur iOS 7.
Deepak GM
1
Il existe un cas où la hauteur de la barre d'état peut être nulle. Si supportedInterfaceOrientations () renvoie UIInterfaceOrientation (résultat incorrect mais aucune erreur de compilation) au lieu de UIInterfaceOrientationMask et qu'un viewcontroller est présenté et rejeté, la hauteur de la barre d'état deviendra nulle.
Cymric
5
La barre d'état de l'iPhone X sera également plus élevée.
avant le
98

Allez avec la suggestion de Martin à la question: Obtenez la hauteur de la barre d'état de l'iPhone .

CGFloat AACStatusBarHeight()
{
    CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
    return MIN(statusBarSize.width, statusBarSize.height);
}

Et dans Swift

func statusBarHeight() -> CGFloat {
    let statusBarSize = UIApplication.shared.statusBarFrame.size
    return Swift.min(statusBarSize.width, statusBarSize.height)
}

Cela ressemble à un hack, mais c'est en fait assez solide. Quoi qu'il en soit, c'est la seule solution qui fonctionne.

Ancienne réponse

Le code suivant, qui irait dans votre sous-classe personnalisée de UIViewController, a presque fonctionné pour prendre en charge le paysage. Mais, j'ai remarqué un boîtier d'angle (en tournant de droite> non pris en charge à l'envers> à gauche) pour lequel cela ne fonctionnait pas (hauteur et largeur changées).

BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);
ma11hew28
la source
Ce n'est pas correct. La hauteur de la barre d'état ne change pas lorsque vous faites pivoter l'appareil. La largeur le ferait, mais le code ci-dessus ne le montre pas, ce n'était pas non plus la question d'origine.
lehn0058
1
Vous avez raison: «la hauteur de la barre d'état ne change pas lorsque vous faites pivoter l'appareil». Mais, comme l'a répondu Ash , "en mode paysage, vous pouvez constater que la largeur et la hauteur sont inversées." Le code ci-dessus en tient compte.
ma11hew28
C'est aussi une question intéressante que je vois maintenant. Cela ressemble à un bug pour moi du côté d'Apple, mais doit encore être pris en compte.
lehn0058
2
@ lehn0058 Ce n'est pas un bug, c'est la façon dont Apple gère la barre en interne. Il est attaché à une fenêtre et cette fenêtre est pivotée à l'aide d'une transformation. Le statusBarFrameest retourné comme valeur avant la transformation.
Leo Natan
1
Il ressemble mieux à une propriété: Dvar statusBarHeight: CGFloat
Pablo A.
23

Essaye ça:

CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

la source
1
la hauteur retournée dans différentes orientations est différente. c'est étrange
tGilani
1
Oui, si la rotation est en mode paysage - [[UIApplication sharedApplication] statusBarFrame] .size.height et [[UIApplication sharedApplication] statusBarFrame] .size.width les valeurs sont commutées.
Guntis Treulands
21

Swift 3 ou Swift 4:

UIApplication.shared.statusBarFrame.height
Wilson
la source
10

Bien que la barre d'état mesure généralement 20 points de hauteur, elle peut être deux fois plus élevée dans certaines situations:

  • lorsque vous êtes au milieu d'un appel téléphonique (c'est un scénario assez courant);
  • lorsque l'enregistreur vocal, ou Skype, ou une application similaire, utilise le microphone en arrière-plan;
  • lorsque le point d'accès personnel est activé;

Essayez-le et vous verrez par vous-même. Le codage en dur de la hauteur à 20 pt fonctionnera généralement, jusqu'à ce qu'il ne fonctionne pas.

J'appuie donc la réponse de H2CO3:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
TotoroTotoro
la source
10

EDIT L'iOS 11 façon de travailler où placer le haut du contenu de votre vue est de UIView safeAreaLayoutGuideVoir la documentation UIView .

RÉPONSES DÉPRÉCIÉES Si vous ciblez iOS 7+, la documentation d'UIViewController indique que la topLayoutGuidepropriété viewController vous donne le bas de la barre d'état ou le bas de la barre de navigation, si elle est également visible. Cela peut être utile et est certainement moins piraté que la plupart des solutions précédentes.

Joshua J. McKinnon
la source
5

N'oubliez pas que le cadre de la barre d'état sera dans l'espace de coordonnées de l'écran! Si vous lancez en mode paysage, vous pouvez constater que la largeur et la hauteur sont inversées. Je vous recommande fortement d'utiliser cette version du code à la place si vous prenez en charge les orientations paysage:

CGRect statusBarFrame = [self.window convertRect:[UIApplication sharedApplication].statusBarFrame toView:view];

Vous pouvez ensuite lire directement la propriété height de statusBarFrame. La «vue» dans ce cas doit être la vue dans laquelle vous souhaitez utiliser les mesures, probablement le contrôleur de vue racine de la fenêtre de l'application.

Par ailleurs, non seulement la barre d'état peut être plus haute pendant les appels téléphoniques, mais elle peut également être nulle si la barre d'état a été délibérément masquée.

Cendre
la source
Cela ne m'a pas donné la bonne hauteur. Mais, j'ai trouvé une méthode différente qui a fonctionné pour moi: stackoverflow.com/a/16598350/242933
ma11hew28
Ouais, c'est un code assez ancien maintenant, donc ce n'est probablement plus une réponse valide. Personnellement, je n'ai plus jamais besoin de vérifier la hauteur de la barre d'état, grâce à la mise en page automatique.
Ash
3

Pour iOS 13, vous pouvez utiliser:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
Eugene Lezov
la source
2

Voici une façon rapide d'obtenir la hauteur de la barre d'état de l'écran:

var screenStatusBarHeight: CGFloat {
    return UIApplication.sharedApplication().statusBarFrame.height
}

Ceux-ci sont inclus en tant que fonction standard dans un de mes projets: https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
la source
1
    var statusHeight: CGFloat!
    if #available(iOS 13.0, *) {
         statusHeight = UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
    } else {
        // Fallback on earlier versions
        statusHeight = UIApplication.shared.statusBarFrame.height
    }
Bassant Ashraf
la source
0

Je viens de trouver un moyen qui vous permet de ne pas accéder directement à la hauteur de la barre d'état, mais de la calculer.

Hauteur de la barre de navigation - topLayoutGuide length = hauteur de la barre d'état

Rapide:

let statusBarHeight = self.topLayoutGuide.length-self.navigationController?.navigationBar.frame.height

self.topLayoutGuide.lengthest la zone supérieure couverte par la barre translucide, et self.navigationController?.navigationBar.frame.heightest la barre translucide à l'exclusion de la barre d'état, qui est généralement de 44 points. Ainsi, en utilisant cette méthode, vous pouvez facilement calculer la hauteur de la barre d'état sans vous soucier du changement de hauteur de la barre d'état en raison des appels téléphoniques.

Henry Ngan
la source
Cela ne fonctionne pas, self.topLayoutGuide.lengthc'est 0 donc le résultat finit par être -44.
nambatee
@nambatee Je crois que cela ne fonctionne plus parce que je suis iOS 11 Apple utilise safeAreaInsets
Henry Ngan
0

Swift 5

UIApplication.shared.statusBarFrame.height

Haspinder Singh
la source
-6

En utilisant le code de ligne unique suivant, vous pouvez obtenir la hauteur de la barre d'état dans n'importe quelle orientation et également si elle est visible ou non

#define STATUS_BAR_HIGHT (
    [UIApplicationsharedApplication].statusBarHidden ? 0 : (
        [UIApplicationsharedApplication].statusBarFrame.size.height > 100 ?
            [UIApplicationsharedApplication].statusBarFrame.size.width :
            [UIApplicationsharedApplication].statusBarFrame.size.height
    )
)

C'est juste une macro simple mais très utile, essayez ceci, vous n'avez pas besoin d'écrire de code supplémentaire

Amol Hirkane
la source