Barra de status do iOS 7 com Phonegap

91

No iOS 7, os aplicativos Phonegap aparecerão abaixo da barra de status. Isso pode dificultar o clique em botões / menus que foram colocados na parte superior da tela.

Existe alguém que conhece uma maneira de corrigir esse problema da barra de status no iOS 7 em um aplicativo Phonegap?

Tentei deslocar a página da web inteira com CSS, mas não parece funcionar. Existe uma maneira de deslocar todo o UIWebView ou apenas fazer a barra de status se comportar como no iOS6?

obrigado

Luddig
fonte
o que exatamente é o "problema da barra de status"? Qualquer código de amostra para reproduzir?
Raptor
1
@ShivanRaptor Com o iOS 7, a barra de status agora faz parte da visualização, então se você tem coisas que estavam no topo da tela com versões anteriores do iOS, agora estão abaixo da barra de status, não automaticamente empurrada logo abaixo dela, que pode causar alguns problemas. Minha sugestão seria criar um wrapper para seu conteúdo e definir uma margem superior de 20px.
Andrew Lively,
@AndrewLively - Isso realmente não funciona quando a página está rolando, há alguma maneira de mover o UIWebView?
Luddig

Respostas:

143

Eu encontrei uma resposta em outro tópico, mas responderei a pergunta caso outra pessoa se pergunte.

Basta substituir o viewWillAppearem MainViewController.mcom este:

- (void)viewWillAppear:(BOOL)animated {
    // View defaults to full size.  If you want to customize the view's size, or its subviews (e.g. webView),
    // you can do so here.
    // Lower screen 20px on ios 7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 20;
        viewBounds.size.height = viewBounds.size.height - 20;
        self.webView.frame = viewBounds;
    }
    [super viewWillAppear:animated];
}
Luddig
fonte
9
Alguém mais está usando isso com o plug-in In App Browser? Se eu configurar o In App Browser como "presentationstyle = fullscreen", uma margem inferior em branco aparecerá depois que o navegador for fechado. Parece que a margem tem a mesma altura da barra de ferramentas InAppBrowser. Definir o tipo de apresentação como "folha de página" corrige isso no iPad, mas o iPhone parece sempre usar "tela inteira". Alguma solução alternativa?
Paulo
1
Muito grato pela resposta - no entanto, o mesmo problema se aplica ao navegador PhoneGap inApp - ele também sobrepõe a barra de status. Alguma ideia para isso?
Michael,
2
Sim, usamos uma versão mais antiga do Cordova (2.3.0) e, para corrigir isso, você terá que definir webViewBounds.origin.y = 20; em createViewsWithOptions. Além disso, veja se a cor de fundo está sendo definida e brinque com isso. Faça uma verificação de versão para iOS7 e superior, assim como nesta excelente resposta de LudWig Kristoffersson.
hnilsen
3
Além disso - se você estiver usando o InAppBrowser, a visualização será reinicializada cada vez que você retornar. Portanto, seria prudente adicionar um sinalizador que diz que já foi executado em seu MainViewController.m.
hnilsen
14
Como esse código é executado em viewWillAppear, você terá problemas com esta solução se seu aplicativo PhoneGap / Cordova exibir outras visualizações nativas (como a caixa de diálogo de captura da câmera) e retornar a esta visualização. A correção para mim foi inicializar 'viewBounds' para '[self.view bounds]' em vez de '[self.webView bounds]'.
Chris Karcher de
37

Além da correção de redimensionamento de Ludwig Kristoffersson, recomendo alterar a cor da barra de status:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 20;
        viewBounds.size.height = viewBounds.size.height - 20;
        self.webView.frame = viewBounds;
    }
    self.view.backgroundColor = [UIColor blackColor];
}
-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}
Alex L
fonte
1
Trabalhando muito bem :) Muito obrigado :)
rkaartikeyan
Perfeito - esta foi a melhor solução para mim.
David Daudelin de
Esta correção funciona localmente após uma compilação do Xcode, mas não depois que eu faço uma compilação do phonegap. Alguma ideia? Eu tenho um aplicativo ios desenvolvido com o phonegap 2.9
DemitryT
Esta solução funciona, mas eu tive um problema com vídeos em tela cheia e encontrei este outro e corrigiu meu problema zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-ios7
magorich
1
@KirankumarSripati na verdade minha última solução foi esta espero que funcione para você NSInteger screenSize = 0; // Global if ([[[UIDevice currentDevice] systemVersion] floatValue]> = 7) {CGRect viewBounds = [self.webView bounds]; viewBounds.origin.y = 20; if (screenSize == 0) {viewBounds.size.height = viewBounds.size.height - 20; screenSize = viewBounds.size.height; } self.webView.frame = viewBounds; } Fiz isso porque meu aplicativo estava redimensionando toda vez que entrava em tela cheia
magorich
22

por favor, instale esse plugin para phonegap: https://build.phonegap.com/plugins/505

E use a configuração correta como abaixo, para controlar a sobreposição da visualização da web:

<preference name="StatusBarOverlaysWebView" value="false" />

Para mim, com Phonegap 3.3.0 funciona.

Mais informações, na página do projeto Github: https://github.com/phonegap-build/StatusBarPlugin

xdemocle
fonte
Muito obrigado por esta resposta !! Eu estava tentando com este plugin: build.phonegap.com/plugins/715 , o problema é que os nomes são os mesmos. Mas nunca funciona para mim. Muito obrigado!!
Jabel Márquez
Para ser sincero, não me lembro se tentei antes esse que você mencionou.
xdemocle
20

Para ocultar a barra de status, adicione o seguinte código no arquivo MainViewController.msob a função-(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
Markmarijnissen
fonte
Isso faz o trabalho. Ele irá ocultar a barra de status tornando seu aplicativo em tela cheia. Eu apenas testei isso no simulador, mas apresentarei um relatório mais tarde, quando executar uma compilação em meus iPhones e iPads.
Rob Evans
Funciona para mim no iOS em um iPad 2
Mark Williams
Isso funciona bem no iPad Air iOS 7.1.2 e não há necessidade de quaisquer alterações ou plug-ins. Ótima resposta, obrigado!
Scriptlabs de
Isso ignora totalmente tudo o que a Apple diz sobre 'modo de tela inteira imersivo "nas Diretrizes de Interface Humana ... só porque você está usando um invólucro em cima do iOS não significa que você pode ignorar os padrões de design ...: /
jesses .co.tt
15

A resposta https://stackoverflow.com/a/19249775/1502287 funcionou para mim, mas tive que mudá-la um pouco para que funcionasse com o plug-in da câmera (e possivelmente outros) e uma metatag de janela de visualização com "height = device- height "(não definir a parte da altura faria com que o teclado aparecesse sobre a vista no meu caso, escondendo algumas entradas ao longo do caminho).

Cada vez que você abriria a visualização da câmera e retornaria ao seu aplicativo, o método viewWillAppear seria chamado e sua visualização diminuiria em 20px.

Além disso, a altura do dispositivo para a janela de visualização incluiria 20 pixels extras, tornando o conteúdo rolável e 20 pixels mais alto do que a visualização da web.

Aqui está a solução completa para o problema da câmera:

Em MainViewController.h:

@interface MainViewController : CDVViewController
@property (atomic) BOOL viewSizeChanged;
@end

Em MainViewController.m:

@implementation MainViewController

@synthesize viewSizeChanged;

[...]

- (id)init
{
    self = [super init];
    if (self) {
        // On init, size has not yet been changed
        self.viewSizeChanged = NO;
        // Uncomment to override the CDVCommandDelegateImpl used
        // _commandDelegate = [[MainCommandDelegate alloc] initWithViewController:self];
        // Uncomment to override the CDVCommandQueue used
        // _commandQueue = [[MainCommandQueue alloc] initWithViewController:self];
    }
    return self;
}

[...]

- (void)viewWillAppear:(BOOL)animated
{
    // View defaults to full size.  If you want to customize the view's size, or its subviews (e.g. webView),
    // you can do so here.
    // Lower screen 20px on ios 7 if not already done
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7 && !self.viewSizeChanged) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 20;
        viewBounds.size.height = viewBounds.size.height - 20;
        self.webView.frame = viewBounds;
        self.viewSizeChanged = YES;
    }
    [super viewWillAppear:animated];
}

Agora, para o problema da janela de visualização, em seu ouvinte de evento deviceready, adicione isto (usando jQuery):

if (window.device && parseFloat(window.device.version) >= 7) {
  $(window).on('orientationchange', function () {
      var orientation = parseInt(window.orientation, 10);
      // We now the width of the device is 320px for all iphones
      // Default height for landscape (remove the 20px statusbar)
      var height = 300;
      // Default width for portrait
      var width = 320;
      if (orientation !== -90 && orientation !== 90 ) {
        // Portrait height is that of the document minus the 20px of
        // the statusbar
        height = document.documentElement.clientHeight - 20;
      } else {
        // This one I found experimenting. It seems the clientHeight
        // property is wrongly set (or I misunderstood how it was
        // supposed to work).
        // Dunno if it's specific to my setup.
        width = document.documentElement.clientHeight + 20;
      }
      document.querySelector('meta[name=viewport]')
        .setAttribute('content',
          'width=' + width + ',' +
          'height=' + height + ',' +
          'initial-scale=1.0,maximum-scale=1.0,user-scalable=no');
    })
    .trigger('orientationchange');
}

Aqui está a janela de visualização que uso para outras versões:

<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0" />

E tudo funciona bem agora.

Dieppe
fonte
Qualquer método sem Jquery @dieppe
Arjun T Raj
simplesmente adicione este código a - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {} método dentro de CDVCamera.m que também resolve o problema da câmera. NSLog (@ "CÂMERA FECHADA"); [[UIApplication sharedApplication] setStatusBarHidden: YES withAnimation: UIStatusBarAnimationNone];
Arjun T Raj
Cara, não sei como dizer obrigado! Tenho lutado com o problema de redução de 20px com a câmera e não consegui encontrar a solução até agora ...
tuks
6

Tente acessar o (app name)-Info.plistarquivo do aplicativo no XCode e adicione as chaves

view controller-based status bar appearance: NO
status bar is initially hidden : YES

Isso funciona para mim sem problemas.

dk123
fonte
Para mim, isso funciona no simulador com uma construção local, mas não no iPad com uma construção remota. Usando PG 3.1 para a construção e iOS7 no simulador e no iPad.
Por Quested Aronsson de
@PerQuestedAronsson Você pode tentar construí-lo localmente no iPad. Estou trabalhando com um iPad iOS7 com phonegap 3.1 sem problemas.
dk123
6

Para Cordova 3.1+, existe um plugin que lida com a mudança no comportamento da barra de status para iOS 7 ou superior.

Isso está muito bem documentado aqui , incluindo como a barra de status pode ser revertida para seu estado pré-iOS7.

Para instalar o plug-in, execute:

cordova plugin add org.apache.cordova.statusbar

Em seguida, adicione isso ao config.xml

<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarStyle" value="default" />
track0
fonte
Você também pode definir a cor do StatusBar, cujo padrão é preto: <preferred name = "StatusBarBackgroundColor" value = "# 000000" /> Veja: plugins.cordova.io/#/package/org.apache.cordova.statusbar
ezzadeen
2
Para Cordova 5+, o plug-in foi renomeado: plug-in cordova adicionar cordova-plugin-statusbar
raider33
5

Eu resolvo meu problema instalando o org.apache.cordova.statusbare adicionando no meu topo config.xml:

<preference name="StatusBarOverlaysWebView" value="false" /> 
<preference name="StatusBarBackgroundColor" value="#000000" />
<preference name="StatusBarStyle" value="lightcontent" />

Essas configurações funcionam apenas para iOS 7 ou superior

Referência: http://devgirl.org/2014/07/31/phonegap-developers-guid/

mayconbelfort
fonte
1

Eu uso o seguinte trecho de código para adicionar uma classe ao corpo, se iOS7 for detectado. Eu, então, estilo essa classe para adicionar uma 20pxmargem no topo do meu contêiner. Certifique-se de ter o plugin "device" instalado e que este código está dentro do evento "deviceready".

Pela leitura, ouvi dizer que a próxima atualização do Phonegap (3.1 eu acredito) oferecerá um suporte melhor às mudanças na barra de status do iOS7. Portanto, isso pode ser necessário apenas como uma correção de curto prazo.

if(window.device && parseFloat(window.device.version) >= 7){
  document.body.classList.add('fix-status-bar');
}
Ryan
fonte
1

Outra maneira é tornar compatível com versões anteriores . Faça o HTML de acordo com iOS 7(com uma margem extra de 20 px no topo) para dar aquela full screenaparência e corte essa margem extra para iOS < 7.0. Algo como o seguinte em MainViewController.m:

- (void)viewDidLoad
{
  [super viewDidLoad];

  if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0) {
    CGRect viewBounds = [self.webView bounds];
    viewBounds.origin.y = -20;
    viewBounds.size.height = viewBounds.size.height + 20;
    self.webView.frame = viewBounds;
  }
}

Esta solução não deixará uma barra preta na parte superior iOS 7.0e superior, o que um usuário moderno do iOS achará estranho e antigo .

tipycalFlow
fonte
0

Escreva o seguinte código dentro de AppDelegate.m no evento didFinishLaunchingWithOptions (exatamente antes de sua última linha de código " return YES; "):

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
{
    [application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
}

Vou aguardar seu feedback! :)

Ehsan
fonte
Este código parece funcionar muito bem para ocultar a barra de status e corrigir o problema. Também dei uma olhada um pouco ontem e encontrei um trecho de código que essencialmente redimensionou o UIWebView e o movi para baixo. Eu adicionei isso como uma resposta também :)
Luddig
Isso é ótimo. Meu código está usando apenas uma maneira simples e fácil de fazer isso! Todos nós estamos fazendo a mesma coisa com métodos diferentes :)
Ehsan,
0

se usarmos o plugin de câmera para a galeria de imagens, a barra de status voltará para corrigir esse problema, adicione esta linha

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

para

- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info {...}

função dentro de CVDCamera.m na lista de plug-ins

Arjun T Raj
fonte
0

Escreva o seguinte código dentro de AppDelegate.m no evento didFinishLaunchingWithOptions na inicialização.

CGRect screenBounds = [[UIScreen mainScreen] bounds]; // Fixing status bar ------------------------------- NSArray *vComp = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; if ([[vComp objectAtIndex:0] intValue] >= 7) { // iOS 7 or above CGRect newWebViewBounds = CGRectMake( 0, 20, screenBounds.size.width, screenBounds.size.height-20 ); screenBounds = newWebViewBounds; } // ------------------------------- Fixing status bar End

E corrigir para iOS 7 acima e acima.

RahulSalvikar
fonte
0

Para manter a barra de status visível em retrato, mas ocultá-la em paisagem (ou seja, tela inteira), tente o seguinte:

Em MainViewController.h:

@interface MainViewController : CDVViewController
@property (atomic) NSInteger landscapeOriginalSize;
@property (atomic) NSInteger portraitOriginalSize;
@end

Em MainViewController.m:

@implementation MainViewController

@synthesize landscapeOriginalSize;
@synthesize portraitOriginalSize;

...

- (void)viewWillAppear:(BOOL)animated
{
    // View defaults to full size.  If you want to customize the view's size, or its subviews (e.g. webView),
    // you can do so here.

    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
}

- (void)orientationChanged:(NSNotification *)notification {
    [self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}

- (void)viewDidDisappear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}

- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        CGRect statusBarFrame = [UIApplication sharedApplication].statusBarFrame;
        CGRect frame = self.webView.frame;

        switch (orientation)
        {
            case UIInterfaceOrientationPortrait:
            case UIInterfaceOrientationPortraitUpsideDown:
            {
                if (self.portraitOriginalSize == 0) {
                    self.portraitOriginalSize = frame.size.height;
                    self.landscapeOriginalSize = frame.size.width;
                }
                frame.origin.y = statusBarFrame.size.height;
                frame.size.height = self.portraitOriginalSize - statusBarFrame.size.height;
            }
                break;

            case UIInterfaceOrientationLandscapeLeft:
            case UIInterfaceOrientationLandscapeRight:
            {
                if (self.landscapeOriginalSize == 0) {
                    self.landscapeOriginalSize = frame.size.height;
                    self.portraitOriginalSize = frame.size.width;
                }
                frame.origin.y = 0;
                frame.size.height = self.landscapeOriginalSize;
            }
                break;
            case UIInterfaceOrientationUnknown:
                break;
        }

        self.webView.frame = frame;
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view from its nib.

    // Change this color value to change the status bar color:
    self.view.backgroundColor = [UIColor colorWithRed:0/255.0f green:161/255.0f blue:215/255.0f alpha:1.0f];
}

Esta é uma combinação do que encontrei neste e nas discussões StackOverflow vinculadas, algum código do plug-in Cordova StatusBar (para não codificar o valor de 20px) e alguns encantamentos de minha parte (não sou um desenvolvedor iOS, portanto Eu me atrapalhei para encontrar essa solução).

matb33
fonte
0

Em primeiro lugar, adicione o plugin Device em seu projeto. O Id do plug-in é: org.apache.cordova.device e o repositório é: https://github.com/apache/cordova-plugin-device.git

Depois disso, use esta função e chame-a em todas as páginas ou telas: -

function mytopmargin() {
    console.log("PLATform>>>" + device.platform);
    if (device.platform === 'iOS') {
        $("div[data-role='header']").css("padding-top", "21px");
        $("div[data-role='main']").css("padding-top", "21px");
    } else {
        console.log("android");
    }
}
Anil Singhania
fonte
0

A melhor maneira de controlar o fundo da barra de status - 2017

Após frustração contínua, muitas pesquisas na Internet, estas são as etapas que você precisa seguir:

  1. Certifique-se de usar o Plug-in da Barra de Status
  2. Adicione esta configuração ao seu config.xml:

<preferência name = "StatusBarOverlaysWebView" value = "false" />

  1. Use o seguinte código em onDeviceReady

        StatusBar.show();
        StatusBar.overlaysWebView(false);
        StatusBar.backgroundColorByHexString('#209dc2');

Funciona para mim em iOS e Android.

Boa sorte!

Niv Asraf
fonte