Barra di stato di iOS 7 con Phonegap


91

In iOS 7, le applicazioni Phonegap appariranno sotto la barra di stato. Ciò può rendere difficile fare clic su pulsanti / menu che sono stati posizionati nella parte superiore dello schermo.

C'è qualcuno che conosce un modo per risolvere questo problema della barra di stato su iOS 7 in un'applicazione Phonegap?

Ho provato a compensare l'intera pagina web con CSS ma non sembra funzionare. Esiste un modo per compensare l'intera UIWebView o semplicemente fare in modo che la barra di stato si comporti come in iOS6?

Grazie


cos'è esattamente il "problema della barra di stato"? Qualche codice di esempio da riprodurre?
Raptor

1
@ShivanRaptor Con iOS 7, la barra di stato ora fa parte della vista, quindi se hai cose che erano nella parte superiore dello schermo con le versioni precedenti di iOS, ora si trovano sotto la barra di stato, non automaticamente spinto proprio sotto di essa, che può causare alcuni problemi. Il mio suggerimento sarebbe quello di creare un wrapper per i tuoi contenuti e impostare un margine superiore di 20px.
Andrew Lively

@AndrewLively - Questo non funziona davvero quando la pagina scorre, esiste un modo per spostare UIWebView?
Luddig

Risposte:


143

Ho trovato una risposta su un altro thread, ma risponderò alla domanda nel caso qualcun altro lo chieda.

Basta sostituire la viewWillAppearin MainViewController.mquesto:

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

9
Qualcun altro lo sta usando con il plugin In App Browser? Se configuro il browser In App come "presentationstyle = fullscreen", dopo la chiusura del browser viene visualizzato un margine inferiore vuoto. Sembra che il margine abbia la stessa altezza della barra degli strumenti di InAppBrowser. L'impostazione del tipo di presentazione su "foglio di pagine" risolve il problema su iPad, ma iPhone sembra utilizzare sempre "schermo intero". Eventuali soluzioni alternative?
Paul

1
Molto grato per la risposta, tuttavia lo stesso problema si applica al browser PhoneGap inApp, si sovrappone anche alla barra di stato. Qualche idea per questo?
Michael

2
Sì, usiamo una versione precedente di Cordova (2.3.0) e per risolvere questo problema dovrai impostare webViewBounds.origin.y = 20; in createViewsWithOptions. Inoltre, controlla se il colore di sfondo è stato impostato e gioca con quello. Fai un controllo della versione per iOS7 e versioni successive, proprio come in questa eccellente risposta di LudWig Kristoffersson.
hnilsen

3
Inoltre, se stai utilizzando InAppBrowser, la vista verrà reinizializzata ogni volta che torni. Quindi sarebbe prudente aggiungere un flag che dice che è già stato eseguito sul tuo MainViewController.m.
hnilsen

14
Poiché questo codice viene eseguito in viewWillAppear, si verificheranno problemi con questa soluzione se l'app PhoneGap / Cordova visualizza altre visualizzazioni native (come la finestra di dialogo di acquisizione della fotocamera) e torna a questa visualizzazione. La soluzione per me era inizializzare "viewBounds" su "[self.view bounds]" invece di "[self.webView bounds]".
Chris Karcher

37

Oltre alla correzione del ridimensionamento di Ludwig Kristoffersson, consiglio di cambiare il colore della barra di stato:

- (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;
}

1
Funziona alla grande :) Grazie
mille

Perfetto: questa era la soluzione migliore per me.
David Daudelin

Questa correzione funziona localmente dopo una build Xcode, ma non dopo aver eseguito una build phonegap. Qualche idea? Ho un'app ios costruita con phonegap 2.9
DemitryT

Questa soluzione funziona ma ho avuto un problema con i video a schermo intero e ho trovato questo altro e ha risolto il mio problema zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-ios7
magorich

1
@KirankumarSripati in realtà la mia ultima soluzione è stata questa, spero che funzioni per te NSInteger screenSize = 0; // Globale 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; } L'ho fatto perché la mia app si ridimensionava ogni volta che
entravo a

22

per favore, installa quel plugin per phonegap: https://build.phonegap.com/plugins/505

E utilizza l'impostazione corretta come di seguito, per controllare l'overlay della visualizzazione web:

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

Per me, con Phonegap 3.3.0 funziona.

Maggiori informazioni, sulla pagina del progetto Github: https://github.com/phonegap-build/StatusBarPlugin


Grazie mille per questa risposta !! Stavo provando con questo plugin: build.phonegap.com/plugins/715 , il problema è che i nomi sono gli stessi. Ma non funziona mai per me. Molte grazie!!
Jabel Marquez

Ad essere sincero, non ricordo se ho provato prima di questo menzionato da te.
xdemocle

20

Per nascondere la barra di stato, aggiungi il seguente codice nel file MainViewController.msotto la funzione-(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Questo fa il lavoro. Nasconderà la barra di stato rendendo la tua app a schermo intero. L'ho testato solo sul simulatore, ma riporterò più tardi quando eseguirò una build sui miei iPhone e iPad.
Rob Evans

Funziona per me su iOS su iPad 2
Mark Williams

Funziona bene su iPad Air iOS 7.1.2 e non sono necessarie modifiche o plug-in. Ottima risposta, grazie!
Scriptlabs

Questo ignora totalmente tutto ciò che Apple dice sulla "modalità a schermo intero immersiva" nelle Linee guida dell'interfaccia umana ... solo perché stai usando un wrapper sopra iOS non significa che puoi ignorare i modelli di progettazione ...: /
jesses .co.tt

15

La risposta https://stackoverflow.com/a/19249775/1502287 ha funzionato per me, ma ho dovuto cambiarla un po 'per farlo funzionare con il plug-in della fotocamera (e potenzialmente altri) e un meta tag viewport con "height = device- altezza "(nel mio caso, la mancata impostazione della parte relativa all'altezza farebbe apparire la tastiera sulla vista, nascondendo alcuni input lungo il percorso).

Ogni volta che apri la vista della fotocamera e torni alla tua app, viene chiamato il metodo viewWillAppear e la tua vista si riduce di 20 px.

Inoltre, l'altezza del dispositivo per la visualizzazione includerebbe i 20 px in più, rendendo il contenuto scorrevole e 20 px più alto della visualizzazione web.

Ecco la soluzione completa per il problema della fotocamera:

In MainViewController.h:

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

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

Ora per il problema del viewport, nel tuo listener di eventi deviceready, aggiungi questo (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');
}

Ecco il viewport che utilizzo per altre versioni:

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

E ora funziona tutto bene.


Qualsiasi metodo senza Jquery @dieppe
Arjun T Raj

aggiungi semplicemente questo codice al metodo - (void) imagePickerController: (UIImagePickerController *) didFinishPickingMediaWithInfo: (NSDictionary *) info {} all'interno di CDVCamera.m che risolve anche il problema della fotocamera. NSLog (@ "FOTOCAMERA CHIUSA"); [[UIApplication sharedApplication] setStatusBarHidden: YES withAnimation: UIStatusBarAnimationNone];
Arjun T Raj

Amico, non conosco le parole per dire grazie! Ho lottato con il problema di restringimento di 20px con la fotocamera e non sono riuscito a trovare la soluzione fino ad ora ...
tuks

6

Prova ad entrare nel (app name)-Info.plistfile dell'app in XCode e aggiungi le chiavi

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

Questo funziona per me senza problemi.


Per me, funziona nel simulatore con una build locale, ma non nell'iPad con una build remota. Utilizzo di PG 3.1 per la build e iOS7 sul simulatore e sull'iPad.
Per Quested Aronsson

@PerQuestedAronsson Potresti provare a crearlo localmente sull'iPad. Sto lavorando con un iPad iOS7 con phonegap 3.1 senza problemi.
dk123

6

Per Cordova 3.1+, esiste un plug-in che si occupa della modifica del comportamento della barra di stato per iOS 7+.

Questo è ben documentato qui , incluso il modo in cui la barra di stato può essere ripristinata al suo stato pre-iOS7.

Per installare il plugin, esegui:

cordova plugin add org.apache.cordova.statusbar

Quindi aggiungilo a config.xml

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

Puoi anche impostare il colore StatusBar che è di default nero: <preferenza name = "StatusBarBackgroundColor" value = "# 000000" /> Vedi: plugins.cordova.io/#/package/org.apache.cordova.statusbar
ezzadeen

2
Per Cordova 5+, il plugin è stato rinominato: cordova plugin add cordova-plugin-statusbar
raider33

5

Risolvo il mio problema installando org.apache.cordova.statusbare aggiungendo nella mia parte superiore config.xml:

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

Queste configurazioni funzionano solo per iOS 7+

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



1

Uso il seguente pezzo di codice per aggiungere una classe al corpo, se viene rilevato iOS7. Quindi modifico quella classe per aggiungere un 20pxmargine nella parte superiore del mio contenitore. Assicurati di avere installato il plugin "device" e che questo codice sia all'interno dell'evento "deviceready".

Dalla lettura in giro, ho sentito che il prossimo aggiornamento di Phonegap (3.1 credo) supporterà meglio le modifiche alla barra di stato di iOS7. Quindi questo potrebbe essere necessario solo come soluzione a breve termine.

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


1

Un altro modo è tornare indietro compatibile . Crea l'HTML secondo iOS 7(con un margine extra di 20px in alto) per dare full screenquell'aspetto e taglia quel margine extra per iOS < 7.0. Qualcosa di simile al seguente in 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;
  }
}

Questa soluzione non lascerà una barra nera iOS 7.0sopra e sopra, cosa che un utente iOS moderno troverà strano e vecchio .


0

Scrivere il seguente codice all'interno AppDelegate.m in didFinishLaunchingWithOptions evento (esattamente prima della sua ultima riga di codice " SI di ritorno; "):

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

Aspetterò il tuo feedback! :)


Questo codice sembra funzionare alla grande per nascondere la barra di stato e risolvere il problema, mi sono anche guardato intorno un po 'ieri e ho trovato una pace di codice che sostanzialmente ha ridimensionato l'UIWebView e spostato verso il basso ho aggiunto anche questo come risposta :)
Luddig

È fantastico. Il mio codice utilizza solo un modo semplice e facile per farlo! Tutti noi stiamo facendo la stessa cosa con metodi diversi :)
Ehsan

0

se utilizziamo il plug-in della fotocamera per la galleria di immagini, la barra di stato tornerà, quindi per risolvere il problema aggiungere questa riga

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

per

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

funzione all'interno di CVDCamera.m nell'elenco dei plugin


0

Scrivere il seguente codice all'interno AppDelegate.m in didFinishLaunchingWithOptions evento alla partenza.

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 correggi per iOS 7 e versioni successive.


0

Per mantenere la barra di stato visibile in verticale ma nasconderla in orizzontale (cioè a schermo intero), prova quanto segue:

In MainViewController.h:

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

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

Questa è una combinazione di ciò che ho trovato in questa e nelle discussioni StackOverflow collegate, un po 'di codice dal plugin Cordova StatusBar (in modo da non codificare il valore 20px) e alcuni incantesimi da parte mia (non sono uno sviluppatore iOS quindi Ho cercato a tentoni questa soluzione).


0

Prima di tutto, aggiungi il plug-in Device nel tuo progetto. L'ID plug-in è: org.apache.cordova.device e il repository è: https://github.com/apache/cordova-plugin-device.git

Dopodiché usa questa funzione e chiamala su ogni pagina o schermo: -

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");
    }
}

0

Il modo migliore per controllare lo sfondo della barra di stato - 2017

Dopo una continua frustrazione, molte ricerche su Internet, questi sono i passaggi che devi compiere:

  1. Assicurati di utilizzare il plug-in della barra di stato
  2. Aggiungi questa impostazione al tuo config.xml:

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

  1. Usa il codice seguente su onDeviceReady

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

Funziona per me su iOS e Android.

In bocca al lupo!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.