iOS 7 - a barra de status se sobrepõe à visualização


109

Eu tenho um ViewControllerque está dentro de um UINavigationcontroller, mas a barra de navegação está oculta. Quando executo o aplicativo no iOS 7, a barra de status é exibida no topo da minha visualização. Há alguma maneira de evitar isto?

Não quero escrever nenhum código específico do sistema operacional.

Insira a descrição da imagem aqui

Tentei definir View controller-based status bar appearancepara NO, mas não corrigiu o problema.


Eu postei minha resposta para mostrar a barra de status como iOS 6 no iOS 7 stackoverflow.com/questions/18294872/…
Desert Rose

2
Você precisa ajustar a origem y e o valor delta também para lidar com o problema da barra de status. Isso pode ajudá-lo a stackoverflow.com/q/18980925/1545180
Ganapathy

Respostas:


95

O Xcode 5 foi iOS 6/7 Deltasfeito especificamente para resolver esse problema. No storyboard, movi minhas visualizações 20 pixels para baixo para parecer certo no iOS 7 e, a fim de torná-lo compatível com iOS 6, mudei Delta ypara -20.

insira a descrição da imagem aqui

Como meu storyboard não usa layout automático, para redimensionar a altura das visualizações corretamente no iOS 6, tive que definir Delta heighttambém Delta Y.


8
sua resposta está certa, mas não funciona com tela de 4 ". Atualize sua resposta se você puder fazer com que funcione com tela de 4" também. Desde já, obrigado.

2
@AnkitMehta Eu não tive que fazer nada específico para 4 "iphones
aryaxt

5
trabalhou para mim. Observe que, para ver esses deltas, você precisa desmarcar 'Usar layout automático' em 'Identidade e tipo' para o storyboard.
marsant

2
Descobri, além de definir um -20 para ∆Y, também tive que definir um +20 para ∆Altura
Toland Hon

3
O que acontece quando a altura da barra de status muda? F.ex .: quando o usuário ativa o ponto de acesso, etc .... a altura é 40px ...
Lukasz

69

Se você simplesmente NÃO deseja nenhuma barra de status, precisa atualizar seu plist com estes dados: Para fazer isso, no plist, adicione essas 2 configurações:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

No iOS 7, espera-se que você projete seu aplicativo tendo em mente uma barra de status transparente sobreposta. Veja o novo aplicativo iOS 7 Weather, por exemplo.


3
Na verdade, essa é a única boa resposta, pois corrige o problema em sua essência da maneira que deveria ser feita. Portanto: votos positivos necessários!
onze 59

5
Pode ser apropriado para algumas situações, mas você deve ter muito cuidado ao ocultar a barra de status. Apenas para visualizações justificadamente em tela inteira, como reprodutores de mídia ou visualizadores de imagens.
smileBot

1
@ eleven59, você quer dizer a forma como os autocratas da Apple pretendem.
JohnK

1
Definitivamente assim é melhor do que alterar o deslocamento de um controlador de visualização (que parece muito sujo).
Benjamin Oman,

ocultar a barra de status não é uma boa ideia ... Eu sei que essa é a maneira mais fácil de lidar com o iOS 7, mas o momento é NECESSÁRIO ...
Fahim Parkar

43

Este é o comportamento padrão UIViewControllerdo iOS 7. A visualização será em tela inteira, o que significa que a barra de status cobrirá a parte superior da visualização.

Se você tiver um UIViewControllerdentro de a UINavigationControllere a navigationBar estiver visível, você pode ter o seguinte código no seu viewDidLoadou ter uma imagem de fundo para a navigationBar fazer o truque.

self.edgesForExtendedLayout = UIRectEdgeNone;

Se você tiver a barra de navegação oculta, terá que ajustar todos os elementos do UIView deslocando 20 pontos. Não vejo outra solução. Usar layout automático ajudará um pouco.

Aqui está o código de amostra para detectar a versão do iOS, se você quiser compatibilidade com versões anteriores.

NSUInteger DeviceSystemMajorVersion() {
    static NSUInteger _deviceSystemMajorVersion = -1;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSString *systemVersion = [UIDevice currentDevice].systemVersion;
        _deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
    });

   return _deviceSystemMajorVersion;
}

18
Em vez de buscar, analisar e comparar a versão do sistema, é recomendável usarif ([self respondsToSelector:@selector(edgesForExtendedLayout)])
Sebastian Hojas

15

Única solução de trabalho que fiz por mim mesmo.

Aqui está minha subclasse UIViewController https://github.com/comonitos/ios7_overlaping

1 subclasse de UIViewController

2 Subclasse seu window.rootViewController dessa classe.

3 Voila!

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect screen = [[UIScreen mainScreen] bounds];
        if (self.navigationController) {
            CGRect frame = self.navigationController.view.frame;
            frame.origin.y = 20;
            frame.size.height = screen.size.height - 20;
            self.navigationController.view.frame = frame;
        } else {
            if ([self respondsToSelector: @selector(containerView)]) {
                UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];

                CGRect frame = containerView.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                containerView.frame = frame;
            } else {
                CGRect frame = self.view.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                self.view.frame = frame;
            }
        }
    }
}

4 Adicione isso para deixar sua barra de status branca logo após a [self.window makeKeyAndVisible]; !!!

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

mas isso não está mostrando o tempo no topo ... Maior desvantagem ... :(
Fahim Parkar

Funciona muito bem, mas para a etapa 4, você deve usar preferredStatusBarStyle em seu controlador de visualização, pois setStatusBarStyle está obsoleto e sua ação padrão é não fazer nada. stackoverflow.com/a/19014724/1192732
CpnCrunch

13
-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

-(void)viewWillLayoutSubviews{

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
  {
    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
        screenHeight = screenRect.size.height;
    else
        screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
    CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
    if (!CGRectEqualToRect(screenFrame, viewFrame1))
    {
        self.view.frame = screenFrame;
        self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }
  }
}

Adicionar chave no plist --- Ver aparência da barra de status baseada no controlador: NÃO


altere a cor da janela se necessário
Darshit Shah

Obrigado, resolveu meu problema de sobreposição. Mas um problema ainda está lá - Ver a aparência da barra de status baseada no controlador: NÃO é para ocultar a barra de status, eu acho. Mas quando eu configuro para SIM, então ele não mostra a barra de status e quando eu configuro para NÃO, ele mostra a barra de status. Então por favor me diga que estou errado com o conceito ou o quê?
Nayan

1
Acho que porque pegar a cor semitransparente padrão definida em didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' e definir no plist Exibir a aparência da barra de status baseada no controlador SIM
Darshit Shah

Muito obrigado! Além disso, apenas para apontar que os documentos da Apple recomendam verificar com if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {}. Felicidades!
Joel Balmer

Muito obrigado. Seu código é muito útil para nós. Precisamos explicar sobre a função viewWillLayoutSubviews.
user3182143

4

Para ocultar a barra de status no ios7, siga estas etapas simples:

No Xcode, vá para a Resourcespasta " " e abra " (app name)-Info.plist file".

  • verifique a View controller based status bar appearancechave " " e defina seu valor " NO"
  • verifique a Status bar is initially hiddenchave " " e defina seu valor " YES"

Se as chaves não estiverem lá, você pode adicioná-las selecionando " information property list" na parte superior e clicando no ícone +


Leia a pergunta claramente, Ele não pediu para ocultar totalmente a barra de status.
ShayanK

1
@AspersionCast: Ele perguntou "Existe uma maneira de evitar isso?" e esta é uma das formas de evitá-lo.
Mandeep Pasbola


3

Se estiver usando xibs, uma implementação muito fácil é encapsular todas as subvisualizações dentro de uma visão de contêiner com sinalizadores de redimensionamento (que você já usará para compatibilidade de 3,5 "e 4") para que a hierarquia de visão seja parecida com esta

hierarquia xib

e, em seguida viewDidLoad, faça algo assim:

- (void)viewDidLoad
{
  [super viewDidLoad];
  // initializations
  if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
  {
    CGRect frame = containerView.frame;
    frame.origin.y += 20;
    frame.size.height -= 20;
    containerView.frame = frame;
  }
}

Dessa forma, as pontas não precisam ser modificadas para compatibilidade com iOS 7. Se você tiver um plano de fundo, ele pode ser mantido do lado de fora containerViewe cobrir toda a tela.


3

Isso é tudo o que é necessário para remover a barra de status. insira a descrição da imagem aqui


2

Para barra de navegação:

Escrevendo este código:

self.navigationController.navigationBar.translucent = NO;

apenas fez o truque para mim.


1

A resposta de Vincent edgeForExtendedLayout funcionou para mim.

Essas macros ajudam a determinar a versão do sistema operacional, tornando mais fácil

// 7.0 and above 
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) 

// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending) 

adicione essas macros ao arquivo prefix.pch do seu projeto e pode ser acessado em qualquer lugar

if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
 //some iOS 7 stuff
 self.edgesForExtendedLayout = UIRectEdgeNone;
}

if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
 // some old iOS stuff
}

1
para mim self.edgesForExtendedLayout = UIRectEdgeNone; não está funcionando ... algum motivo por quê?
Fahim Parkar


0

Se você quiser que "Use Autolayout" seja habilitado a qualquer custo, coloque o seguinte código em viewdidload.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
{
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.extendedLayoutIncludesOpaqueBars = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
}

0

Minha barra de status e barra de navegação se sobrepõem após retornar da visualização horizontal do YTPlayer. Aqui está minha solução depois de tentar a versão @comonitos, mas não funciona no meu iOS 8

- (void)fixNavigationBarPosition {
    if (self.navigationController) {
        CGRect frame = self.navigationController.navigationBar.frame;
        if (frame.origin.y != 20.f) {
            frame.origin.y = 20.f;
            self.navigationController.navigationBar.frame = frame;
        }
    }
}

Basta chamar esta função sempre que quiser fixar a posição da barra de navegação. Eu chamei YTPlayerViewDelegate'splayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.