Como obter programaticamente a altura da barra de status do iOS

277

Sei que atualmente a barra de status (com o tempo, a bateria e a conexão de rede) na parte superior do iPhone / iPad é de 20 pixels para telas sem retina e 40 pixels para telas com retina, mas para a prova futura do meu aplicativo eu gostaria para poder determinar isso sem valores de codificação. É possível descobrir a altura da barra de status programaticamente?

lehn0058
fonte

Respostas:

506

[UIApplication sharedApplication].statusBarFrame.size.height. Mas como todos os tamanhos estão em pontos, não em pixels, a altura da barra de status sempre é igual a 20.

Atualizar. Vendo esta resposta sendo considerada útil, devo elaborar.

A altura da barra de status é, de fato, igual a 20.0f pontos, exceto nos seguintes casos:

  • barra de status foi ocultada com o setStatusBarHidden:withAnimation:método e sua altura é igual a 0,0f pontos;
  • como o @Anton apontou aqui, durante uma chamada recebida fora do aplicativo Phone ou durante a altura da barra de status da sessão de gravação de som é igual a 40,0f pontos.

Há também um caso de barra de status que afeta a altura da sua visualização. Normalmente, a altura da vista é igual à dimensão da tela para determinada orientação menos a altura da barra de status. No entanto, se você animar a barra de status (mostrar ou ocultar) após a exibição, a barra de status mudará seu quadro, mas a exibição não será exibida. , será necessário redimensionar manualmente a exibição após a animação da barra de status (ou durante a animação desde a altura da barra de status é definida como o valor final no início da animação).

Atualização 2. Há também um caso de orientação da interface do usuário. A barra de status não respeita o valor da orientação; portanto, o valor da altura da barra de status para o modo retrato é [UIApplication sharedApplication].statusBarFrame.size.height(sim, a orientação padrão é sempre retrato, não importa o que o aplicativo info.plist diz), para paisagem - [UIApplication sharedApplication].statusBarFrame.size.width. Para determinar a orientação atual da interface do usuário quando estiver fora UIViewControllere self.interfaceOrientationnão estiver disponível, use [UIApplication sharedApplication].statusBarOrientation.

Atualização para iOS7. Embora o estilo visual da barra de status tenha mudado, ele ainda está lá, seu quadro ainda se comporta da mesma maneira. A única interessante encontrar cerca de barra de status Eu tenho - Eu share: o seu UINavigationBar's azulejos de fundo também vai estar lado a lado para a barra de status, de modo que você pode conseguir alguns efeitos interessantes de design ou apenas colorir sua barra de status. Isso também não afetará a altura da barra de status de forma alguma.

O fundo lado a lado da barra de navegação também é lado a lado na barra de status

Kyr Dunenkoff
fonte
6
Este método produz 1024 (iOS7)
Marc
1
@MarcMosby, veja minha atualização. Lembrou-se desta edição - obrigado por você.
Kyr Dunenkoff
2
Sim, como Marc apontou no iOS7, você cria 1024 às vezes e 20 às vezes. Portanto, essa não é mais uma maneira à prova de idiotas de determinar a altura. Duvido que isso seja devido à natureza transparente da barra de status no iOS 7. Pode ser que, primeiro ele vá para tela cheia e depois se redimensione. Portanto, se você aplicar consultas durante essa transição, poderá obter o valor errado. Pode ser chamar esse método com uma ajuda de atraso força no iOS 7.
Deepak GM
1
Há um caso em que a altura da barra de status pode ser zero. Se supportedInterfaceOrientations () retornar UIInterfaceOrientation (resultado incorreto, mas nenhum erro do compilador) em vez de UIInterfaceOrientationMask e um viewcontroller for apresentado e descartado, a altura da barra de status será zero.
Cymric
5
Também na barra de status do iPhone X será maior.
antes
98

Siga a sugestão de Martin para a pergunta: Obter a altura da barra de status do iPhone .

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

E em Swift

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

Parece um hack, mas na verdade é bastante sólido. Enfim, é a única solução funcional.

Resposta antiga

O código a seguir, que entraria em sua subclasse personalizada de UIViewController, quase funcionou para dar suporte ao cenário. Porém, notei uma caixa de canto (ao girar da direita> sem suporte de cabeça para baixo> esquerda) para a qual não funcionava (altura e largura alteradas).

BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);
ma11hew28
fonte
Isso não está correto. A altura da barra de status não muda quando você gira o dispositivo. A largura seria, mas o código acima não mostra isso, nem era a pergunta original.
Lehn0058 17/05
1
Você está certo de que "a altura da barra de status não muda quando você gira o dispositivo". Mas, como Ash respondeu , "no modo paisagem, você pode descobrir que largura e altura são trocadas". O código acima leva isso em consideração.
Ma11hew28
Esta é uma questão interessante que eu tenho visto agora também. Parece um bug para mim do lado da Apple, mas ainda precisa ser contabilizado.
lehn0058
2
@ lehn0058 Não é um bug, é como a Apple lida com a barra internamente. Ele é anexado a uma janela e essa janela é girada usando uma transformação. O statusBarFrameé retornado como o valor antes da transformação.
Leo Natan
1
Parece melhor como uma propriedade: Dvar statusBarHeight: CGFloat
Pablo A.
23

Tente o seguinte:

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

fonte
1
a altura retornada em diferentes orientações é diferente. Isso é estranho
tGilani
1
Sim, se a rotação for paisagem - os valores [[UIApplication sharedApplication] statusBarFrame] .size.height e [[UIApplication sharedApplication] statusBarFrame] .size.width são alterados.
Guntis Treulands
21

Swift 3 ou Swift 4:

UIApplication.shared.statusBarFrame.height
Wilson
fonte
10

Embora a barra de status geralmente tenha 20 pontos de altura, pode ser o dobro dessa quantidade em algumas situações:

  • quando você está no meio de uma ligação (esse é um cenário bastante comum);
  • quando o gravador de voz, o Skype ou um aplicativo semelhante estiver usando o microfone em segundo plano;
  • quando o Hotspot pessoal estiver ativado;

Apenas tente e você verá por si mesmo. Codificar a altura para 20pt normalmente funcionará, até que não funcione.

Então eu segundo a resposta do H2CO3:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
Macondo2Seattle
fonte
10

EDITAR A maneira do iOS 11 de descobrir onde colocar o topo do conteúdo da visualização é na safeAreaLayoutGuideConsulte a documentação do UIView .

Resposta obsoleta Se você está direcionando o iOS 7+, a documentação do UIViewController aconselha que a topLayoutGuidepropriedade viewController fornece a parte inferior da barra de status ou a parte inferior da barra de navegação, se também estiver visível. Isso pode ser útil e certamente é menos invasivo do que muitas das soluções anteriores.

Joshua J. McKinnon
fonte
5

Não esqueça que o quadro da barra de status estará no espaço de coordenadas da tela! Se você iniciar no modo paisagem, poderá descobrir que largura e altura são trocadas. Eu recomendo fortemente que você use esta versão do código caso suporte as orientações da paisagem:

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

Você pode ler diretamente a propriedade height do statusBarFrame. 'View' nesse caso deve ser a vista em que você deseja fazer uso das medições, provavelmente o controlador de vista raiz da janela do aplicativo.

Aliás, não apenas a barra de status pode ser mais alta durante as chamadas telefônicas, como também pode ser zero se a barra de status tiver sido deliberadamente oculta.

Cinza
fonte
Isso não me deu a altura correta. Mas, eu encontrei outra maneira que funcionou para mim: stackoverflow.com/a/16598350/242933
ma11hew28
Sim, este é um código bastante antigo agora, portanto provavelmente não é mais uma resposta válida. Pessoalmente, não tenho mais necessidade de verificar a altura da barra de status, graças ao layout automático.
Ash
2

Aqui está uma maneira rápida de obter a altura da barra de status da tela:

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

Eles estão incluídos como uma função padrão em um projeto meu: https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
fonte
2

Para o iOS 13, você pode usar:

UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
Eugene Lezov
fonte
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
fonte
0

Acabei de encontrar uma maneira de permitir que você não acesse diretamente a altura da barra de status, mas calcule-a.

Altura da barra de navegação - comprimento do topLayoutGuide = altura da barra de status

Rápido:

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

self.topLayoutGuide.lengthé a área superior coberta pela barra translúcida e self.navigationController?.navigationBar.frame.heighté a barra translúcida, excluindo a barra de status, que geralmente é de 44 pontos. Portanto, usando esse método, você pode calcular facilmente a altura da barra de status sem se preocupar com a alteração da altura da barra de status devido a chamadas telefônicas.

Henry Ngan
fonte
Isso não funciona, self.topLayoutGuide.lengthé 0, então o resultado acaba sendo -44.
Nambatee 31/10
@nambatee Eu acredito que não funciona mais porque eu sou iOS 11 Apple usa safeAreaInsets
Henry Ngan
0

Swift 5

UIApplication.shared.statusBarFrame.height

Haspinder Singh
fonte
-6

Usando o código de linha única a seguir, você pode obter a altura da barra de status em qualquer orientação e também se estiver visível ou não

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

É apenas uma macro simples, mas muito útil, tente isso, você não precisa escrever nenhum código extra

Amol Hirkane
fonte