Barra de status do iOS 7 de volta ao estilo padrão do iOS 6 no aplicativo para iPhone?


292

No iOS 7, UIStatusBarele foi projetado de uma maneira que se funde com a visualização da seguinte maneira:

GUI projetada por Tina Tavčar (GUI projetada por Tina Tavčar )

  • É legal, mas atrapalha um pouco a sua exibição quando você tem algo na parte superior da tela e fica sobreposto à barra de status.

  • Existe uma solução simples (como definir uma propriedade em info.plist) que possa mudar a maneira como ela funciona [sem se sobrepor] de volta a como está no iOS6?

  • Eu sei que uma solução mais direta é ter self.view.center.x+ 20 pontos para cada controlador de exibição, mas alterá-los estragará outras dimensões (ter um diferente self.view.center.xpode causar problemas para sequências personalizadas, etc.) e, de repente, ele se transforma em um trabalho tedioso. melhor ser evitado.

  • Ficarei realmente feliz se alguém puder me fornecer uma solução unilateral para isso.

PS Eu sei que posso ocultar a barra de status fazendo coisas como ter

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

No didFinishLaunchingWithOptionsmétodo, mas isso é uma solução alternativa, um atalho para evitar o problema, por isso não considero isso uma solução real.


6
Infelizmente, as barras de status pretas foram descontinuadas no ios 7
i_duhh_bomb

Eu vou concordar com @GangstaGraham. Essas cores são simplesmente lindas ! Para responder sua pergunta, receio que você não possa. A razão pela qual a barra de status foi projetada dessa maneira agora é porque a translucidez é a nova novidade do iOS e foi projetada para dar "profundidade" a um aplicativo, dizendo que ela está em cima de algo, então há algo por baixo.
Cole Johnson

Você já tentou definir o preferidoStatusBarStyle como UIStatusBarDefault? Caixa iOS 7 UIViewController Documentação
theaob

1
O fato de ter UIStatusBarDefaultpara a barra de status apenas torna seu conteúdo preto na cor. Não fará com que ela funcione de volta ao modo como está no iOS6.
何魏奇 奇 说 - 何魏奇 Archy Will He

2
Alguma sorte com isso? Eu amo o iOS7, mas essa coisa está me deixando louco!
Mihai Fratu

Respostas:


449

Isso é postado cruzadamente em uma postagem de blog que escrevi , mas aqui está o resumo completo das barras de status, barras de navegação e controladores de exibição de contêiner no iOS 7:

  1. Não há como preservar o layout da barra de status no estilo do iOS 6. A barra de status sempre se sobrepõe ao seu aplicativo no iOS 7

  2. Não confunda a aparência da barra de status com o layout da barra de status. A aparência (clara ou padrão) não afeta o layout da barra de status (quadro / altura / sobreposição). É importante observar também que a barra de status do sistema não possui mais cor de fundo. Quando a API se refere a UIStatusBarStyleLightContent, elas significam texto em branco em um plano de fundo claro. UIStatusBarStyleDefault é texto em preto em um plano de fundo claro.

  3. A aparência da barra de status é controlada por um dos dois caminhos básicos mutuamente exclusivos: você pode defini-los programaticamente da maneira tradicional ou o UIKit atualizará a aparência para você com base em algumas novas propriedades do UIViewController. A última opção está ativada por padrão. Verifique o valor essencial do seu aplicativo em "Aparência da barra de status com base no ViewController" para ver qual deles você está usando. Se você definir esse valor como YES, todos os controladores de exibição de nível superior em seu aplicativo (exceto um controlador de exibição de contêiner UIKit padrão) precisarão substituir o preferidoStatusBarStyle, retornando o estilo padrão ou o estilo leve. Se você editar o valor plist para NO, poderá gerenciar a aparência da barra de status usando os métodos familiares do UIApplication.

  4. O UINavigationController alterará a altura do seu UINavigationBar para 44 ou 64 pontos, dependendo de um conjunto de restrições bastante estranho e não documentado. Se o UINavigationController detectar que a parte superior do quadro da visualização é visualmente contígua à parte superior do UIWindow, ele desenha sua barra de navegação com uma altura de 64 pontos. Se o topo de sua exibição não for contíguo ao topo do UIWindow (mesmo que desapareça apenas um ponto), ele desenha sua barra de navegação da maneira “tradicional”, com uma altura de 44 pontos. Essa lógica é executada pelo UINavigationController, mesmo que haja vários filhos dentro da hierarquia do controlador de exibição do seu aplicativo. Não há como impedir esse comportamento.

  5. Se você fornecer uma imagem de plano de fundo da barra de navegação personalizada com apenas 44 pontos (88 pixels) de altura e os limites da visualização do UINavigationController corresponderem aos limites da UIWindow (conforme discutido em # 4), o UINavigationController desenhará sua imagem no quadro (0,20,320 , 44), deixando 20 pontos de espaço em preto opaco acima da sua imagem personalizada. Isso pode confundi-lo ao pensar que você é um desenvolvedor inteligente que ignorou a regra 1, mas você está enganado. A barra de navegação ainda tem 64 pontos de altura. A incorporação de um UINavigationController em uma hierarquia de exibição de estilo slide-a-revelador deixa isso bem claro.

  6. Cuidado com a propriedade edgeForExtendedLayout de UIViewController de nome confuso. Ajustar edgeForExtendedLayout não faz nada na maioria dos casos. A única maneira pela qual o UIKit usa essa propriedade é se você adicionar um controlador de exibição a um UINavigationController, e o UINavigationController usar edgeForExtendedLayout para determinar se o controlador de exibição filho deve ou não estar visível embaixo da área da barra de navegação / barra de status. A configuração de edgeForExtendedLayout no UINavigationController não faz nada para alterar se o UINavigationController tem ou não uma área de barra de navegação com 44 ou 64 pontos de altura. Veja o item 4 para essa lógica. Uma lógica de layout semelhante se aplica à parte inferior da sua exibição ao usar uma barra de ferramentas ou UITabBarController.

  7. Se tudo o que você está tentando fazer é impedir que seu controlador de exibição filho personalizado fique sobre a barra de navegação quando estiver dentro de um UINavigationController, defina edgeForExtendedLayout como UIRectEdgeNone (ou pelo menos uma máscara que exclua UIRectEdgeTop). Defina esse valor o mais cedo possível no ciclo de vida do seu controlador de exibição.

  8. O UINavigationController e o UITabBarController também tentarão preencher os contentInsets dos modos de exibição de tabela e de coleção em sua hierarquia de subvisões. Isso é feito de maneira semelhante à lógica da barra de status do item 4. Existe uma maneira programática de evitar isso, definindo automaticamenteAdjustsScrollViewInsets como NO para suas visualizações de tabela e de coleção (o padrão é YES). Isso apresentou alguns problemas sérios para o Whisper e o Riposte, pois usamos os ajustes contentInset para controlar o layout das visualizações da tabela em resposta aos movimentos da barra de ferramentas e do teclado.

  9. Para reiterar: não há como retornar à lógica de layout da barra de status no estilo do iOS 6. Para aproximar isso, é necessário mover todos os controladores de exibição do seu aplicativo para uma exibição de contêiner que é deslocada em 20 pontos a partir da parte superior da tela, deixando uma exibição intencionalmente preta atrás da barra de status para simular a aparência antiga. Esse é o método que acabamos usando no Riposte e no Whisper.

  10. A Apple está se esforçando muito para garantir que você não tente fazer o # 9. Eles querem que redesenhamos todos os nossos aplicativos para sobrepor a barra de status. Existem muitos argumentos convincentes, no entanto, tanto pela experiência do usuário quanto por razões técnicas, por que nem sempre é uma boa idéia. Você deve fazer o melhor para seus usuários e não simplesmente seguir o capricho da plataforma.


35
Só queria acrescentar que você pode adicionar uma restrição ao que estiver na parte superior da sua visualização para anexar ao guia de layout superior - isso deixará um espaço em branco atrás da barra de status (que você pode preencher com a cor que desejar) mas também permitirá que a visualização se ajuste automaticamente à posição correta no iOS 6. Dessa forma, você não precisa ajustar manualmente a posição de suas visualizações no código.
BreadicalMD

4
Essa é uma solução brilhante. Você expôs minha ignorância no AutoLayout. Melhor seguir isso.
precisa saber é o seguinte

1
Se você colocar o espaço superior do objeto abaixo da borda da guia de layout superior, poderá usar o controle de restrição para adicionar uma restrição de espaçamento vertical ao vizinho mais próximo, que agora será o guia de layout superior. Como alternativa, você pode usar ctrl + click do seu objeto no guia de layout superior para adicionar uma restrição de espaçamento vertical explicitamente.
precisa saber é o seguinte

2
@BreadicalMD Uma parte que não entendo é que -topLayoutGuide não está disponível no iOS 6, isso significa que você precisa usar diferentes restrições de layout automático no iOS 7 e 6?
Jeremy

1
Ótima resposta ... Mas eu tenho uma dúvida 1) UINavigationController alterando a parte da altura.Por favor, explique um pouco mais. graças
user1010819

122

Atualizações em 19 de setembro de 2013:

corrigidos erros de escala adicionando self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);

erros de digitação corrigidos na NSNotificationCenterdeclaração


Atualizações em 12 de setembro de 2013:

corrigido UIViewControllerBasedStatusBarAppearanceparaNO

adicionou uma solução para aplicativos com rotação de tela

adicionou uma abordagem para alterar a cor de fundo da barra de status.


Aparentemente, não há como reverter a barra de status do iOS7 para como ela funciona no iOS6.

No entanto, sempre podemos escrever alguns códigos e transformar a barra de status no estilo iOS6, e esta é a maneira mais rápida de obter:

  1. Defina UIViewControllerBasedStatusBarAppearancecomo NOin info.plist(para optar por não permitir que os controladores de exibição ajustem o estilo da barra de status para que possamos definir o estilo da barra de status usando o método UIApplicationstatusBarStyle.)

  2. No AppDelegate application:didFinishLaunchingWithOptions, ligue para

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        [application setStatusBarStyle:UIStatusBarStyleLightContent];
        self.window.clipsToBounds =YES;
        self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
    
        //Added on 19th Sep 2013
        self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
    }
    return YES;
    


a fim de:

  1. Verifique se é o iOS 7.

  2. Defina o conteúdo da barra de status como branco, em oposição a UIStatusBarStyleDefault.

  3. Evite a exibição de subvisões cujos quadros ultrapassem os limites visíveis (para vistas que animam na vista principal de cima).

  4. Crie a ilusão de que a barra de status ocupa espaço como no iOS 6, deslocando e redimensionando a moldura da janela do aplicativo.


Para aplicativos com rotação de tela,

use o NSNotificationCenter para detectar alterações de orientação adicionando

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];

em if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)e criar um novo método em AppDelegate:

- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
    int a = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
    int w = [[UIScreen mainScreen] bounds].size.width;
    int h = [[UIScreen mainScreen] bounds].size.height;
    switch(a){
        case 4:
            self.window.frame =  CGRectMake(0,20,w,h);
            break;
        case 3:
            self.window.frame =  CGRectMake(-20,0,w-20,h+20);
            break;
        case 2:
            self.window.frame =  CGRectMake(0,-20,w,h);
            break;
        case 1:
           self.window.frame =  CGRectMake(20,0,w-20,h+20);
    }
}

Para que, quando a orientação for alterada, ele acionará uma instrução de chave para detectar a orientação da tela do aplicativo (Retrato, De cabeça para baixo, Paisagem à esquerda ou Paisagem à direita) e alterar o quadro da janela do aplicativo, respectivamente, para criar a ilusão da barra de status do iOS 6.


Para alterar a cor de fundo da sua barra de status:

Adicionar

 @property (retain, nonatomic) UIWindow *background;

em AppDelegate.hfazer backgrounduma propriedade em sua classe e evitar ARC de retirar a atribuição-lo. (Você não precisa fazer isso se não estiver usando o ARC.)

Depois disso, você só precisa criar o UIWindow em if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1):

background = [[UIWindow alloc] initWithFrame: CGRectMake(0, 0, self.window.frame.size.width, 20)];
background.backgroundColor =[UIColor redColor];
[background setHidden:NO];

Não se esqueça de @synthesize background;depois @implementation AppDelegate!


3
Isso quebra na rotação. apenas um heads-up
Jesse Naugher

2
@JesseNaugher Eu recomendo modificar a restrição de espaçamento vertical de 0 a 20 programaticamente. Funcionará em rotação.
expert

2
Alguma idéia de como podemos evitar que a barra de navegação se expanda em 20 pixels? Esta solução é boa para mim, mas minha barra de navegação tem 20 pixels de altura.
precisa saber é

4
@ArchyHolt: Sua solução simples funciona para mim, exceto quando apresento um controlador de exibição modal. Depois que o controlador de exibição modal é descartado, a exibição restante fica agora na barra de status. Eu reproduzi isso em um novo projeto de amostra para garantir que não haja mais nada descolado. Acho que talvez sua solução mais avançada possa ser útil aqui, mas não tenho certeza de qual notificação entraria em jogo. Alguma ideia?
markdorison

4
A exibição é redefinida após o descarte de um controlador de exibição modal. :(
KarenAnne 26/09/2013

41

ATUALIZAÇÃO (NOVA SOLUÇÃO)

Esta atualização é a melhor solução para o problema da barra de navegação do iOS 7. Você pode definir um exemplo de cor da barra de navegação: FakeNavBar.backgroundColor = [UIColor redColor];

Nota: Se você usar o Navigation Controller padrão, use a solução antiga.

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
    {
        UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
        FakeNavBar.backgroundColor = [UIColor whiteColor];

        float navBarHeight = 20.0;
        for (UIView *subView in self.window.subviews) {

            if ([subView isKindOfClass:[UIScrollView class]]) {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
            } else {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
            }
        }
        [self.window addSubview:FakeNavBar];
    }

    return YES;

}

SOLUÇÃO ANTIGA - Se você usar o código anterior, ignore o seguinte Código e Imagem

Esta é a versão antiga da solução da barra de navegação do iOS 7.

Resolvi o problema com o seguinte código. Isto é para adicionar uma barra de status. didFinishLaunchingWithOptions

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    UIView *addStatusBar = [[UIView alloc] init];
    addStatusBar.frame = CGRectMake(0, 0, 320, 20);
    addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
    [self.window.rootViewController.view addSubview:addStatusBar];
}

E para o Interface Builder, isso é para quando você abre com o iOS 6; está começando em 0 pixels.

Nota: O iOS 6/7 Deltas será exibido apenas se você desmarcar "Usar Autolayout" para o View Controller no "File Inspector" (ícone à esquerda) no painel de detalhes.

Digite a descrição da imagem aqui


6
Você fez o meu dia.Tome +1 pela ajuda!
Niru Mukund Shah

5
Observação: os deltas do iOS 6/7 são exibidos apenas se você desmarcar "Usar autolayout" para o View Controller no "File Inspector" (ícone à esquerda) no painel de detalhes.
26413 Matt

1
Muito obrigado! Você me salvou de muitos problemas!
neowinston

2
Quem disse que o layout da barra de status no estilo do iOS 6 não pode ser mantido, você pode fazer isso de maneira @ TacettinÖzbölük ... obrigado, companheiro, por esta solução awsum.
Vizllx

1
Agradável! além disso, apenas para observar que a apple prefere isso agora: if (NSFoundationVersionNumber> = NSFoundationVersionNumber_iOS_6_1) {}
Joel Balmer

26

SOLUÇÃO:

Defina-o no seu viewcontroller ou no rootviewcontroller substituindo o método:

-(BOOL) prefersStatusBarHidden
    {
        return YES;
    }

Não é uma solução ruim. Remova completamente a barra. Pode não ser ideal para UX o tempo todo, mas praticável.
Farhan Hafeez 26/09

Simplesmente impressionante. Trabalhou para mim na perfeição.
madLokesh

Cenário: Depois de voltar ao UIVIew depois de reproduzir o vídeo em tela cheia, uma barra preta aparece na parte inferior, que é do tamanho da barra de status, embora eu já estivesse usando uma barra de status. Eu removi a barra de status completamente e agora o problema foi corrigido.
madLokesh

Eu só tive sucesso usando esse método #
user2277872

17

Aqui está outra abordagem para projetos que fazem uso extensivo do Storyboard:

OBJETIVO:

O objetivo dessa abordagem é recriar o mesmo estilo da barra de status no iOS7 que existia no iOS6 (consulte o título da pergunta "Barra de status do iOS 7 Voltar ao estilo do iOS 6?").

RESUMO:

Para conseguir isso, usamos o Storyboard, tanto quanto possível, deslocando os elementos da interface do usuário que são sobrepostos pela barra de status (no iOS 7) para baixo, enquanto usamos deltas para reverter a alteração de layout para baixo no iOS 6.1 ou anterior. O espaço extra resultante no iOS 7 é então ocupado por um UIView com o backgroundColor definido como uma cor de nossa escolha. O último pode ser criado em código ou usando o Storyboard (consulte ALTERNATIVES abaixo)

PREMISSAS:

Para obter o resultado desejado ao seguir as etapas abaixo, supõe-se que View controller-based status bar appearanceesteja definido como NÃO e que você Status bar styleesteja definido como "Estilo preto transparente (alfa de 0,5)" ou "Estilo preto opaco". Ambas as configurações podem ser encontradas / ou adicionadas em "Informações" nas configurações do seu projeto.

PASSOS:

  • Adicione uma subvisão ao UIWindow para servir como plano de fundo da barra de status. Para conseguir isso, adicione o seguinte ao AppDelegate application: didFinishLaunchingWithOptions:apósmakeKeyAndVisible

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        UIView *statusBarBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, yourAppsUIWindow.frame.size.width, 20)];
        statusBarBackgroundView.backgroundColor = [UIColor blackColor];
        [yourAppsUIWindow addSubview:statusBarBackgroundView];
    }
    
  • Como você adicionou programaticamente um plano de fundo apenas para o iOS 7, será necessário ajustar o layout dos elementos da interface do usuário que se sobrepõem à barra de status, preservando o layout para o iOS6. Para conseguir isso, faça o seguinte:

    • Verifique Use Autolayoutse a opção Desmarcado está desmarcada (porque, caso contrário, "iOS 6/7 Deltas" não é mostrado no Inspetor de tamanhos). Para fazer isso:
      • selecione seu arquivo Storyboard
      • show Utilitários
      • selecione "Mostrar o inspetor de arquivos"
      • Em "Documento do Construtor de Interface", desmarque a opção "Usar Autolayout"
    • Opcionalmente, para ajudá-lo a monitorar as alterações de layout para os iOS 7 e 6 à medida que você as aplica, selecione o "Editor Assistente", selecione "Visualizar" e "iOS 6.1 ou anterior": insira a descrição da imagem aqui insira a descrição da imagem aqui
    • Agora selecione o elemento da interface do usuário que você deseja ajustar para que não fique mais sobreposto pela barra de status
    • Selecione "Mostrar o inspetor de tamanho" na coluna Utilitários
    • Reposicione seu elemento da interface do usuário ao longo do eixo Y pela mesma quantidade que a altura da barra de status bg: insira a descrição da imagem aqui
    • E altere o valor do iOS6 / 7 Deltas para Y pela mesma quantidade NEGATIVA da altura da barra de status bg (observe a alteração na visualização do iOS 6, se você estiver usando): insira a descrição da imagem aqui

ALTERNATIVAS:

Para adicionar ainda menos código em projetos pesados ​​de storyboard e ter a auto-rotação do segundo plano da barra de status, em vez de adicionar um segundo plano programaticamente à sua barra de status, você pode adicionar uma visualização colorida a cada controlador de visualização localizado na parte superior da visualização principal do referido controlador de visualização. Em seguida, você alteraria o delta da altura dessa nova visualização para o mesmo valor negativo que a altura da sua visualização (para desaparecer no iOS 6).

A desvantagem dessa alternativa (embora talvez insignificante, considerando a compatibilidade da autorotação) é o fato de que essa visualização extra não é imediatamente visível se você estiver visualizando o Storyboard para iOS 6. Você só saberia que ela existe se você desse uma olhada no " Resumo do documento "do Storyboard.


12

Se você não deseja que seus controladores de exibição sejam sobrepostos pela barra de status (e pelas barras de navegação), desmarque a caixa "Estender arestas sob as barras superiores" no Interface Builder no Xcode 5.

Desmarque a opção Estender arestas sob as barras superiores


7
Isso só é possível se você usar um storyboard
Cœur

3
Ele só funciona com recipientes vcs como controlador de navegação ou controlador tabbar
Andrea

2
edgeForExtendedLayout é usado apenas pelos controladores de exibição de contêiner (como UINavigationController) para determinar se as exibições de seus filhos devem ser sobrepostas pelo cromo do pai. Definir esta propriedade no controlador de exibição raiz para o UIWindow não faz nada. Veja a minha resposta acima: stackoverflow.com/questions/18294872/…
jaredsinclair

Como você faz isso para um UITabBarController @Andrea? Obrigado.
precisa saber é o seguinte

@KarenAnne Depende se você faz programaticamente ou com storyboards. Programaticamente, você só precisa definir a propriedade edgeForExtent como desejar no controlador de exibição que está mostrando dentro do UITabBarViewController, mas para não ter o problema da barra de status, você deve carregar um controlador de navegação dentro do UITabbarController. Verifique aqui. developer.apple.com/library/ios/documentation/UserExperience/…
Andrea

11

A Apple lançou as Perguntas e respostas técnicas QA1797: Impedindo que a barra de status cubra suas visualizações . Funciona bem para as versões iOS 6 e iOS 7.


5
A Apple está assumindo que todos estão usando o layout automático. O layout automático foi horrível no Xcode 4, e o Xcode 5 foi lançado recentemente, então essa é uma suposição duvidosa.
Glenn Maynard

1
Mas, em perspectiva, essa é uma solução melhor do que redimensionar o quadro da janela raiz ou da barra de status.
Igor

Pelo que sei, a solução da Apple não funcionará se o seu rootViewController for um splitViewController.
Vern Jensen 4/10

8

Eu já vi muitos, muitos, muitos e muitos tutoriais para corrigir esse problema. Mas nenhum deles funciona! Aqui está a minha solução e funciona para mim:

if( [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f ) {
    float statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
    for( UIView *v in [self.view subviews] ) {
        CGRect rect = v.frame;
        rect.origin.y += statusBarHeight;
        v.frame = rect;
    }
}

A lógica é simples. Eu mudo todas as visões de crianças no self.view com 20 pixels. Isso é tudo. Em seguida, a captura de tela será exibida exatamente como o iOS 6. Eu odeio a barra de status do iOS7! ~ "~


2
onde devo adicionar isso? no aplicativo delegado foi iniciado com opções?
Mhmdshawqi

Quando eu fizer isso, minha barra de status fica branco
ROPO

6

Uma pequena alternativa à resposta de Archy Holt, um pouco mais simples:

uma. Defina UIViewControllerBasedStatusBarAppearancecomo NOem info.plist

b. Em AppDelegate's application:didFinishLaunchingWithOptions:, chamada:

if ([[UIDevice currentDevice].systemVersion floatValue] < 7)
{
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
else
{
    // handling statusBar (iOS7)
    application.statusBarStyle = UIStatusBarStyleLightContent;
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
    self.window.clipsToBounds = YES;

    // handling screen rotations for statusBar (iOS7)
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}

E adicione o método:

- (void)applicationDidChangeStatusBarOrientationNotification:(NSNotification *)notification
{
    // handling statusBar (iOS7)
    self.window.frame = [UIScreen mainScreen].applicationFrame;
}

Você também pode considerar a subclasse UIWindowpara se auto -manipular UIApplicationDidChangeStatusBarOrientationNotification.


você tem algum problema com o presentViewController: animated: conclusão:?
Tùng Đỗ

@ Verdadeiro, então eu fiz uma alternativa que funciona melhor: stackoverflow.com/questions/18294872/…
Cœur

5

Eu usei isso em todos os meus controladores de exibição, é simples. Adicione essas linhas em todos os seus métodos viewDidLoad:

- (void)viewDidLoad{
    //add this 2 lines:
    if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

    [super viewDidLoad];
}

1
Trabalhou como um encanto, e fácil de morrer. Em movimento rubi, antes da chamada para super-utilização: self.edgesForExtendedLayout = UIRectEdgeNone se respondsToSelector ( "edgesForExtendedLayout")
tehprofessor

4

Tente este método simples ....

Etapa 1 : alterar em um únicoviewController

[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleBlackOpaque];

Etapa 2 : alterar em todo o aplicativo

info.plist
      ----> Status Bar Style
                  --->UIStatusBarStyle to UIStatusBarStyleBlackOpaque

Etapa 3 : adicione isso em cada um viewWillAppearpara ajustar a statusbaraltura paraiOS7

    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 7) {
        CGRect frame = [UIScreen mainScreen].bounds;
        frame.origin.y+=20.0;
        frame.size.height-= 20.0;
        self.view.frame = frame;
        [self.view layoutIfNeeded];
    }


3

Atingi a barra de status como o iOS 6 no iOS 7.

Defina UIViewControllerBasedStatusBarAppearance como NO em info.plist

Coloque este código no - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptionsmétodo

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    [application setStatusBarStyle:UIStatusBarStyleLightContent];
    self.window.clipsToBounds =YES;
    self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height);

    //Added on 19th Sep 2013
    NSLog(@"%f",self.window.frame.size.height);
    self.window.bounds = CGRectMake(0,0, self.window.frame.size.width, self.window.frame.size.height);
}

Pode empurrar para baixo todas as suas visualizações em 20 pixels.Para mais, use o seguinte código no -(void)viewDidAppear:(BOOL)animatedmétodo

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    CGRect frame=self.view.frame;
    if (frame.size.height==[[NSUserDefaults standardUserDefaults] floatForKey:@"windowHeight"])
    {
        frame.size.height-=20;
    }
    self.view.frame=frame;
}

Você deve definir o valor windowHeight Userdefaults após a alocação da janela no método didFinishLauncing, como

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[[NSUserDefaults standardUserDefaults] setFloat:self.window.frame.size.height forKey:@"windowHeight"];

Uma abordagem melhor é tornar o seu UINavigationBar heightigual a 64 em vez de 44. Em seguida, sua barra se estenderá até o topo, como nos aplicativos da Apple.
precisa

@AaronBrager Mas minha exigência era mostrar a barra de status no estilo iOS 6.
Desert Rose

Você pode adicionar a solução para o Landscape Orientation iOS 7 ?. Estou fazendo a mesma coisa. mas não está funcionando no iOS 7 Landscape.
Sathiamoorthy

@DesertRose THX! Isso funciona para mim, mas corta a barra do uitabbar na parte inferior. Eu tenho um aplicativo baseado em controlador de barra de guias com 3 visualizações, duas das quais são controladoras de tableview.
Marciokoko

1
Até que eu gire o dispositivo (meu dispositivo iOS 7 é um iPad), isso o corrige perfeitamente. Mas uma vez que eu giro, a barra preta permanece exatamente onde está e a "visualização" (desculpe se esse é o termo técnico errado, eu sou um cara do PhoneGap / web) mantém sua altura reduzida - exceto que não é mais a altura, é a largura. Esta solução não suporta rotação, mas é a melhor correção que já vi - como pode ser aprimorada para observar as rotações do dispositivo? Obrigado!
tylerl

2

Se você estiver usando o construtor de interface, tente o seguinte:

No seu arquivo xib:

1) Selecione a vista principal, defina a cor do plano de fundo para preto (ou qualquer cor que você deseja que a barra de status seja

2) Verifique se o plano de fundo é uma subvisão independente, posicionada como um filho de nível superior da visualização do controlador.
Mova seu plano de fundo para se tornar um filho direto da visão do controlador. Verifique o painel de dimensionamento automático para garantir que você bloqueou todas as arestas do quadro, ativou os dois eixos de flexibilidade e, se for um UIImageView, defina o modo de conteúdo como Escala para preencher. Programaticamente, isso se traduz em contentMode definido como UIViewContentModeScaleToFill e tem sua máscara de redimensionamento automático definida como (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight).

3) Agora mova tudo o que está bloqueado de cima para baixo em 20 pts e defina um delta do iOS 6/7 para Y -20.
Todos os filhos de nível superior que estão bloqueados no quadro superior no painel de dimensionamento automático precisam ser movidos para baixo em 20pts e ter o delta do iOS 6/7 em Y definido para -20. (Cmd selecione todos esses itens e clique na seta para baixo 20 vezes - existe uma maneira melhor de alguém?)

4) Ajuste a altura delta do iOS 6/7 de todos os itens acima que tinham uma altura flexível. Qualquer um dos itens bloqueados na parte superior e inferior do quadro e com a altura flexível ativada no painel de dimensionamento automático também deve ter a altura delta do iOS 6/7 definida como 20. Isso inclui a exibição de plano de fundo mencionada acima. Isso pode parecer anti-intuitivo, mas devido à ordem em que eles são aplicados, é necessário. A altura do quadro é definida primeiro (com base no dispositivo), depois os deltas são aplicados e, finalmente, as máscaras de dimensionamento automático são aplicadas com base nas posições de deslocamento de todos os quadros filhos - pense um pouco sobre isso, fará sentido.

5) Finalmente, os itens que foram bloqueados no quadro inferior, mas não no quadro superior, não precisam de deltas.

Isso fornecerá a barra de status idêntica no iOS7 e iOS6.

Por outro lado, se você deseja estilizar o iOS7 enquanto mantém a compatibilidade com o iOS6, defina os valores delta Y / delta height como 0 para a visualização em segundo plano.

Para ver mais informações sobre a migração do iOS7, leia a publicação completa: http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html


Não deltas quando se utiliza layout de auto
lostintranslation

2

Minha solução foi adicionar um UIViewcom altura de 20 pontos no topo da janela quando no iOS 7. Então eu criei um método na minha classe AppDelegate para exibir / ocultar a fundo barra de status "sólida". Em application:didFinishLaunchingWithOptions::

// ...

// Add a status bar background
self.statusBarBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.bounds.size.width, 20.0f)];
self.statusBarBackground.backgroundColor = [UIColor blackColor];
self.statusBarBackground.alpha = 0.0;
self.statusBarBackground.userInteractionEnabled = NO;
self.statusBarBackground.layer.zPosition = 999; // Position its layer over all other views
[self.window addSubview:self.statusBarBackground];

// ...
return YES;

Então eu criei um método para desvanecer / desabilitar o fundo preto da barra de status:

- (void) showSolidStatusBar:(BOOL) solidStatusBar
{
    [UIView animateWithDuration:0.3f animations:^{
        if(solidStatusBar)
        {
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
            self.statusBarBackground.alpha = 1.0f;
        }
        else
        {
            [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
            self.statusBarBackground.alpha = 0.0f;
        }
    }];
}

Tudo o que tenho a fazer agora é ligar [appDelegate showSolidStatusBar:YES]quando necessário.


2

Esse pode ser um problema esmagador se você usar o layout Automático porque não poderá mais manipular quadros diretamente. Existe uma solução simples sem muito trabalho.

Acabei escrevendo um método utilitário em uma classe Utility e o chamei de todos os viewDidLayoutSubviewsmétodos dos controladores de exibição .

+ (void)addStatusBarIfiOS7:(UIViewController *)vc
    {
        if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
            CGRect viewFrame = vc.view.frame;
            if(viewFrame.origin.y == 20) {
                //If the view's y origin is already 20 then don't move it down.
                return;
            }
            viewFrame.origin.y+=20.0;
            viewFrame.size.height-= 20.0;
            vc.view.frame = viewFrame;
            [vc.view layoutIfNeeded];
        }
    }

Substitua seu viewDidLayoutSubviewsmétodo no controlador de exibição, onde deseja a barra de status. Isso o levará ao fardo do Autolayout.

- (void)viewDidLayoutSubviews
{
    [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
    [super viewDidLayoutSubviews];
    [MyUtilityClass addStatusBarIfiOS7:self];
}

1

A maneira mais fácil de fazer isso é instalar um SDK mais antigo no seu mais novo Xcode.

Como instalar o SDK mais antigo no Xcode mais recente?

  1. Você pode obter o SDK do iOS 6.1 em http://www.4shared.com/zip/NlPgsxz6/iPhoneOS61sdk.html ou fazer o download de um Xcode mais antigo e obter o SDK de seu conteúdo

  2. Descompacte e cole esta pasta em /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs

  3. Reinicie o xcode.

  4. Agora você pode selecionar um SDK mais antigo nas configurações de compilação do seu projeto

Espero que ajude você. Funcionou para mim =)


trabalhou para mim. obrigado @marcelosalloum, mas ainda estou procurando uma solução alternativa para o meu aplicativo phonegap (uiwebview) para suportar a barra de status transparente do iOS7 para futuras atualizações do meu aplicativo. obrigado novamente. ;)
hanism

@marcellosaloum, você tem certeza de que o aplicativo será aceito pela Apple? Eles disseram que os aplicativos compilados com o XCode 4 não seriam mais aceitos ... isso significa o iOS 6 SDK.
Valerio

Meu aplicativo foi realmente aceito porque o Xcode5 pode compilar SDKs do iOS mais antigos. Não tenho certeza se o AppStore rejeitará os aplicativos criados pelo Xcode4, mas (Xcode4! = IOS 6 SDK) como você disse.
Marcelosalloum

Isso foi depois de 1º de fevereiro? Naquele dia, a Apple tornou isso obrigatório.
Valerio

Não, o último toque nesse código no ano passado, pessoal. Não sabia que a Apple havia feito isso obrigatório (mas não estou feliz em saber). Você poderia postar aqui o link que diz isso? Cheers
marcelosalloum

1

Ao usar a presentViewController:animated:completion:bagunça window.rootViewController.view, tive que encontrar uma abordagem diferente para esse problema. Finalmente consegui trabalhar com modais e rotações subclassificando a UIView do meu rootViewController.

.h

@interface RootView : UIView

@end

.m

@implementation RootView

-(void)setFrame:(CGRect)frame
{
    if (self.superview && self.superview != self.window)
    {
        frame = self.superview.bounds;
        frame.origin.y += 20.f;
        frame.size.height -= 20.f;
    }
    else
    {
        frame = [UIScreen mainScreen].applicationFrame;
    }

    [super setFrame:frame];
}

- (void)layoutSubviews
{
    self.frame = self.frame;

    [super layoutSubviews];
}

@end

Agora você tem uma forte solução alternativa para animações do iOS7.


1

Estou atrasado para esta resposta, mas só quero compartilhar o que fiz, que é basicamente a solução mais fácil

Primeiro de tudo-> Vá para o seu info.plistarquivo e adicione Estilo da barra de status-> Estilo preto transparente (Alfa de 0,5)

Agora, aqui vai: -

Adicione este código no seu AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
     //Whatever your code goes here
  if(kDeviceiPad){

     //adding status bar for IOS7 ipad
         if (IS_IOS7) {
              UIView *addStatusBar = [[UIView alloc] init];
              addStatusBar.frame = CGRectMake(0, 0, 1024, 20);
              addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //change this to match your navigation bar
              [self.window.rootViewController.view addSubview:addStatusBar];
                    }
                }
    else{

         //adding status bar for IOS7 iphone
        if (IS_IOS7) {
            UIView *addStatusBar = [[UIView alloc] init];
            addStatusBar.frame = CGRectMake(0, 0, 320, 20);
            addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //You can give your own color pattern
            [self.window.rootViewController.view addSubview:addStatusBar];
        }

    return YES;
   }

0

Minha solução muito simples (supondo que você tenha apenas orientação vertical suportada) é redefinir os limites da janela do aplicativo para versões do iOS abaixo de 7, no delegado do aplicativo, método didFinishLaunchingWithOptions:

CGRect screenBounds = [[UIScreen mainScreen] bounds];
if ([HMService getIOSVersion] < 7) {
    // handling statusBar (iOS6) by leaving top 20px for statusbar.
    screenBounds.origin.y = 20;
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}
else {
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}

Seu código apenas altera o 'y' de 0 para 20, mas não ajusta a altura de maneira adequada, portanto, você deve adicionar screenBounds.size.height - = 20; logo após screenBounds.origin.y = 20;
Amit C.

0

Você pode ocultar a barra de status todos juntos. Portanto, seu aplicativo será exibido em tela cheia. Eu acho que é o melhor que você terá.

UIStatusBarStyleNone ou definido nas configurações de destino.


2
onde especificar UIStatusbarstylenone
user4951 23/08

0

Etapas para ocultar a barra de status no iOS 7:

1. Acesse o arquivo info.plist do aplicativo.

2.E definir, exibir a aparência da barra de status baseada em controlador: Booleano NÃO

Espero ter resolvido o problema da barra de status .....


0

Para continuar trabalhando com setStatusBarHidden: eu uso esta categoria:

@interface UIApplication (StatusBar)

-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden;

@end

@implementation UIApplication (StatusBar)

-(void)setIOS7StatusBarHidden:(BOOL)statusBarHidden{
    if (!IOS7) {
        [self setStatusBarHidden:statusBarHidden];
        return;
     }

    if ([self isStatusBarHidden] == statusBarHidden) {
        return;
    }

    [self setStatusBarHidden:statusBarHidden];
    [self keyWindow].clipsToBounds = YES;
    CGFloat offset = statusBarHidden ? 0 : 20;
    [self keyWindow].frame =  CGRectMake(0,offset,[self keyWindow].frame.size.width,[self keyWindow].frame.size.height-offset);
    [self keyWindow].bounds = CGRectMake(0, offset, [self keyWindow].frame.size.width,[self keyWindow].frame.size.height);
}

@end


0

Pode ser tarde demais para compartilhar, mas tenho algo a contribuir que pode ajudar alguém. Estava tentando subclassificar o UINavigationBar e queria fazer com que parecesse o ios 6 com barra de status preta e texto da barra de status em branco.

Aqui está o que eu achei trabalhando para isso

        self.navigationController?.navigationBar.clipsToBounds = true
        self.navigationController?.navigationBar.translucent = false
        self.navigationController?.navigationBar.barStyle = .Black
        self.navigationController?.navigationBar.barTintColor = UIColor.whiteColor()

Tornou o fundo da barra de status preto, o texto da barra de status em branco e a cor da barra de navegação em branco.

iOS 9.3, XCode 7.3.1

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.