Barra de estado de iOS 7 con Phonegap

91

En iOS 7, las aplicaciones Phonegap aparecerán debajo de la barra de estado. Esto puede dificultar el hacer clic en los botones / menús que se han colocado en la parte superior de la pantalla.

¿Hay alguien que sepa cómo solucionar este problema de la barra de estado en iOS 7 en una aplicación Phonegap?

Intenté compensar toda la página web con CSS, pero no parece funcionar. ¿Hay alguna manera de compensar todo el UIWebView o simplemente hacer que la barra de estado se comporte como lo hizo en iOS6?

Gracias

Luddig
fuente
¿Qué es exactamente el "problema de la barra de estado"? ¿Algún código de muestra para reproducir?
Raptor
1
@ShivanRaptor Con iOS 7, la barra de estado ahora es parte de la vista, por lo que si tiene cosas que estaban en la parte superior de la pantalla con versiones anteriores de iOS, ahora están debajo de la barra de estado, no presionadas automáticamente justo debajo, lo que puede causar algunos problemas. Mi sugerencia sería crear un contenedor para su contenido y establecer un margen superior de 20px.
Andrew Lively
@AndrewLively: esto realmente no funciona cuando la página se desplaza, ¿hay alguna forma de mover UIWebView?
Luddig

Respuestas:

143

Encontré una respuesta en otro hilo, pero responderé la pregunta en caso de que alguien más se pregunte.

Basta con sustituir el viewWillAppearen MainViewController.mesto:

- (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
fuente
9
¿Alguien más está usando esto con el complemento In App Browser? Si configuro In App Browser como "presentationstyle = fullscreen", aparecerá un margen inferior en blanco después de cerrar el navegador. Parece que el margen tiene la misma altura que la barra de herramientas InAppBrowser. Configurar el tipo de presentación en "hoja de página" corrige esto en iPad, pero el iPhone parece usar siempre "pantalla completa". ¿Alguna solución?
Paul
1
Muy agradecido por la respuesta, sin embargo, el mismo problema se aplica al navegador PhoneGap inApp, también se superpone a la barra de estado. ¿Alguna idea para eso?
Michael
2
Sí, usamos una versión anterior de Cordova (2.3.0), y para solucionar esto tendrás que configurar webViewBounds.origin.y = 20; en createViewsWithOptions. Además, vea si se está configurando el color de fondo y juegue con eso. Verifique la versión para iOS7 y superior, como en esta excelente respuesta de LudWig Kristoffersson.
hnilsen
3
Además, si está utilizando InAppBrowser, la vista se reiniciará cada vez que regrese. Por lo tanto, sería prudente agregar una bandera que diga que ya se ha ejecutado en MainViewController.m.
hnilsen
14
Debido a que este código se ejecuta en viewWillAppear, tendrá problemas con esta solución si su aplicación PhoneGap / Cordova muestra otras vistas nativas (como el cuadro de diálogo de captura de la cámara) y vuelve a esta vista. La solución para mí fue inicializar 'viewBounds' en '[self.view limits]' en lugar de '[self.webView limits]'.
Chris Karcher
37

Además de la corrección de cambio de tamaño de Ludwig Kristoffersson, recomiendo cambiar el color de la barra de estado:

- (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
fuente
1
Funciona muy bien :) Muchas gracias :)
rkaartikeyan
Perfecto, esta fue la mejor solución para mí.
David Daudelin
Esta solución funciona localmente después de una compilación de Xcode, pero no después de que hago una compilación de phonegap. ¿Algunas ideas? Tengo una aplicación para iOS construida con phonegap 2.9
DemitryT
Esta solución funciona pero tuve un problema con los videos de pantalla completa y encontré este otro y solucionó mi problema zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-ios7
magorich
1
@KirankumarSripati en realidad mi última solución fue esta Espero que esto funcione para usted NSInteger screenSize = 0; // Global if ([[[UIDevice currentDevice] systemVersion] floatValue]> = 7) {CGRect viewBounds = [self.webView límites]; viewBounds.origin.y = 20; if (screenSize == 0) {viewBounds.size.height = viewBounds.size.height - 20; screenSize = viewBounds.size.height; } self.webView.frame = viewBounds; } Hice eso porque mi aplicación
cambiaba de
22

por favor, instale ese complemento para phonegap: https://build.phonegap.com/plugins/505

Y use la configuración correcta como a continuación, para controlar la superposición de la vista web:

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

Para mí, con Phonegap 3.3.0 funciona.

Más información, en la página del proyecto Github: https://github.com/phonegap-build/StatusBarPlugin

xdemocle
fuente
¡¡Muchas gracias por esta respuesta !! Estaba probando con este complemento: build.phonegap.com/plugins/715 , el problema es que los nombres son los mismos. Pero nunca me funciona. ¡¡Muchas gracias!!
Jabel Márquez
Para ser honesto, no recuerdo si lo intenté antes de este mencionado por ti.
xdemocle
20

Para ocultar la barra de estado, agregue el siguiente código en el archivo MainViewController.mdebajo de la función-(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
Markmarijnissen
fuente
Esto hace el trabajo. Ocultará la barra de estado haciendo que tu aplicación esté en pantalla completa. Solo probé esto en el simulador, pero informaré más tarde cuando ejecute una compilación en mis iPhones y iPads.
Rob Evans
Funciona para mí en iOS en un iPad 2
Mark Williams
Esto funciona bien en iPad Air iOS 7.1.2 y no es necesario realizar cambios ni complementos. ¡Gran respuesta, gracias!
Scriptlabs
Esto ignora por completo todo lo que dice Apple sobre el "modo de pantalla completa inmersiva" en las Pautas de la interfaz humana ... el hecho de que esté usando un contenedor en la parte superior de iOS no significa que pueda ignorar los patrones de diseño ...: /
jesses .co.tt
15

La respuesta https://stackoverflow.com/a/19249775/1502287 funcionó para mí, pero tuve que cambiarlo un poco para que funcionara con el complemento de la cámara (y potencialmente con otros) y una metaetiqueta de la ventana gráfica con "height = device- height "(no establecer la parte de altura haría que el teclado apareciera sobre la vista en mi caso, ocultando algunas entradas en el camino).

Cada vez que abría la vista de la cámara y volvía a su aplicación, se llamaría al método viewWillAppear y su vista se reduciría en 20px.

Además, la altura del dispositivo para la ventana gráfica incluiría los 20 px adicionales, lo que hace que el contenido sea desplazable y 20 px más alto que la vista web.

Aquí está la solución completa para el problema de la cámara:

En MainViewController.h:

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

En 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];
}

Ahora para el problema de la ventana gráfica, en su detector de eventos listo para el dispositivo, agregue esto (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');
}

Aquí está la ventana gráfica que uso para otras versiones:

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

Y todo funciona bien ahora.

dieppe
fuente
Cualquier método sin Jquery @dieppe
Arjun T Raj
simplemente agregue este código al método - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {} dentro de CDVCamera.m que también resuelve el problema de la cámara. NSLog (@ "CÁMARA CERRADA"); [[UIApplication sharedApplication] setStatusBarHidden: SÍ withAnimation: UIStatusBarAnimationNone];
Arjun T Raj
¡Hombre, no sé las palabras para decir gracias! He estado luchando con el problema de encogimiento de 20px con la cámara y no pude encontrar la solución hasta ahora ...
tuks
6

Intente ingresar al (app name)-Info.plistarchivo de la aplicación en XCode y agregue las claves

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

Esto funciona para mí sin problema.

dk123
fuente
Para mí, esto funciona en el simulador con una compilación local, pero no en el iPad con una compilación remota. Usando PG 3.1 para la compilación e iOS7 en el simulador y el iPad.
Per Quested Aronsson
@PerQuestedAronsson Es posible que desee intentar compilarlo localmente en el iPad. Estoy trabajando con un iPad iOS7 con phonegap 3.1 sin problema.
dk123
6

Para Cordova 3.1+, hay un complemento que se ocupa del cambio en el comportamiento de la barra de estado para iOS 7+.

Esto está bien documentado aquí , incluido cómo la barra de estado se puede revertir a su estado anterior a iOS7.

Para instalar el complemento, ejecute:

cordova plugin add org.apache.cordova.statusbar

Luego agregue esto a config.xml

<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarStyle" value="default" />
track0
fuente
También puede establecer el color de la barra de estado, que por defecto es negro: <preferencia name = "StatusBarBackgroundColor" value = "# 000000" /> Consulte: plugins.cordova.io/#/package/org.apache.cordova.statusbar
ezzadeen
2
Para Cordova 5+, el complemento ha sido renombrado: cordova plugin add cordova-plugin-
statusbar
5

Resuelvo mi problema instalando org.apache.cordova.statusbary agregando en mi parte superior config.xml:

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

Estas configuraciones solo funcionan para iOS 7+

Referencia: http://devgirl.org/2014/07/31/phonegap-developers-guid/

mayconbelfort
fuente
1

Utilizo la siguiente pieza de código para agregar una clase al cuerpo, si se detecta iOS7. Luego le doy estilo a esa clase para agregar un20px margen en la parte superior de mi contenedor. Asegúrese de tener instalado el complemento "dispositivo" y que este código esté dentro del evento "deviceready".

Después de leer, escuché que la próxima actualización de Phonegap (3.1, creo) admitirá mejor los cambios en la barra de estado de iOS7. Por lo tanto, esto puede ser necesario como una solución a corto plazo.

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

Otra forma es la compatibilidad con versiones anteriores . Haga el HTML de acuerdo con iOS 7(con un margen adicional de 20px en la parte superior) para darle ese full screenaspecto y corte ese margen adicional para iOS < 7.0. Algo como lo siguiente en 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 solución no dejará una barra negra en la parte superior iOS 7.0y superior, lo que un usuario moderno de iOS encontrará extraño y antiguo .

tipycalFlow
fuente
0

Escriba el siguiente código dentro de AppDelegate.m en el evento didFinishLaunchingWithOptions (exactamente antes de su última línea de código " return YES; "):

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

¡Esperaré tus comentarios! :)

Ehsan
fuente
Este código parece funcionar muy bien para ocultar la barra de estado y solucionar el problema, también miré un poco ayer y encontré una paz de código que esencialmente cambió el tamaño de UIWebView y lo movió hacia abajo. También agregué esto como respuesta :)
Luddig
Eso es genial. ¡Mi código solo usa una forma simple y fácil de hacerlo! Todos estamos haciendo lo mismo con diferentes métodos :)
Ehsan
0

si usamos el complemento de la cámara para la galería de imágenes, la barra de estado volverá, así que para solucionar ese problema, agregue esta línea

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

a

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

función dentro de CVDCamera.m en la lista de complementos

Arjun T Raj
fuente
0

Escriba el siguiente código dentro de AppDelegate.m en el evento didFinishLaunchingWithOptions al inicio.

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

Y arregle para iOS 7 y superior.

RahulSalvikar
fuente
0

Para mantener la barra de estado visible en vertical pero ocultarla en horizontal (es decir, pantalla completa), intente lo siguiente:

En MainViewController.h:

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

En 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 es una combinación de lo que encontré en esto y las discusiones vinculadas de StackOverflow, algo de código del complemento Cordova StatusBar (para no codificar el valor de 20px), y algunos encantamientos de mi parte (no soy un desarrollador de iOS, así que Busqué a tientas mi camino hacia esta solución).

matb33
fuente
0

En primer lugar, agregue el complemento de dispositivo en su proyecto. La identificación del complemento es: org.apache.cordova.device y el repositorio es: https://github.com/apache/cordova-plugin-device.git

Después de eso, use esta función y llámela en cada página o pantalla: -

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
fuente
0

La mejor manera de controlar el fondo de la barra de estado - 2017

Después de una frustración constante, muchas búsquedas en Internet, estos son los pasos que debe seguir:

  1. Asegúrese de utilizar el complemento de la barra de estado
  2. Agregue esta configuración a su config.xml:

<nombre de preferencia = "StatusBarOverlaysWebView" value = "false" />

  1. Utilice el siguiente código en onDeviceReady

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

Me funciona en iOS y Android.

¡Buena suerte!

Niv Asraf
fuente