Barre d'état iOS 7 avec Phonegap

91

Dans iOS 7, les applications Phonegap apparaîtront sous la barre d'état. Cela peut rendre difficile le clic sur les boutons / menus qui ont été placés en haut de l'écran.

Y a-t-il quelqu'un qui connaît un moyen de résoudre ce problème de barre d'état sur iOS 7 dans une application Phonegap?

J'ai essayé de compenser la page Web entière avec CSS mais cela ne semble pas fonctionner. Existe-t-il un moyen d'aimer le décalage de toute l'UIWebView ou simplement de faire en sorte que la barre d'état se comporte comme elle le faisait dans iOS6?

Merci

Luddig
la source
quel est exactement le "problème de la barre d'état"? Un exemple de code à reproduire?
Raptor
1
@ShivanRaptor Avec iOS 7, la barre d'état fait maintenant partie de la vue, donc si vous avez des éléments qui étaient en haut de l'écran avec les versions iOS précédentes, ils se trouvent maintenant sous la barre d'état, pas automatiquement poussés juste en dessous, ce qui peut causer des problèmes. Ma suggestion serait de créer un wrapper pour votre contenu et de définir une marge supérieure de 20 px.
Andrew Lively
@AndrewLively - Cela ne fonctionne pas vraiment lorsque la page défile, existe-t-il un moyen de déplacer UIWebView?
Luddig

Réponses:

143

J'ai trouvé une réponse sur un autre fil, mais je répondrai à la question au cas où quelqu'un d'autre se demanderait.

Remplacez simplement le viewWillAppearin MainViewController.mpar ceci:

- (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
la source
9
Quelqu'un d'autre l'utilise-t-il avec le plug-in In App Browser? Si je configure le navigateur In App comme "presentationstyle = fullscreen", une marge inférieure vide apparaît après la fermeture du navigateur. Il semble que la marge soit de la même hauteur que la barre d'outils InAppBrowser. Définir le type de présentation sur «feuille de pages» résout ce problème sur iPad, mais l'iPhone semble toujours utiliser «plein écran». Des solutions de contournement?
Paul
1
Très reconnaissant pour la réponse - mais le même problème s'applique au navigateur PhoneGap inApp - il recouvre également la barre d'état. Des idées pour ça?
Michael
2
Oui, nous utilisons une ancienne version de Cordova (2.3.0), et pour résoudre ce problème, vous devrez définir webViewBounds.origin.y = 20; dans createViewsWithOptions. Vérifiez également si la couleur d'arrière-plan est définie et jouez avec cela. Faites une vérification de version pour iOS7 et supérieur, comme dans cette excellente réponse de LudWig Kristoffersson.
hnilsen
3
De plus, si vous utilisez InAppBrowser, la vue se réinitialisera à chaque retour. Il serait donc prudent d'ajouter un indicateur indiquant qu'il a déjà été exécuté sur votre MainViewController.m.
hnilsen
14
Étant donné que ce code s'exécute dans viewWillAppear, vous rencontrerez des problèmes avec cette solution si votre application PhoneGap / Cordova affiche d'autres vues natives (comme la boîte de dialogue de capture de l'appareil photo) et revient à cette vue. Le correctif pour moi était d'initialiser «viewBounds» sur «[self.view bounds]» au lieu de «[self.webView bounds]».
Chris Karcher
37

En plus du correctif de redimensionnement de Ludwig Kristoffersson, je recommande de changer la couleur de la barre d'état:

- (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
la source
1
Working Great :) Merci beaucoup :)
rkaartikeyan
Parfait - c'était la meilleure solution pour moi.
David Daudelin
Ce correctif fonctionne localement après une construction Xcode, mais pas après une construction phonegap. Des idées? J'ai une application iOS construite avec phonegap 2.9
DemitryT
Cette solution fonctionne mais j'ai eu un problème avec les vidéos en plein écran et j'ai trouvé cette autre et cela a résolu mon problème zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-ios7
magorich
1
@KirankumarSripati en fait ma dernière solution était celle-ci, j'espère que cela fonctionne pour vous 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; } Je l'ai fait parce que mon application se redimensionnait à chaque fois que je
passais en
22

s'il vous plaît, installez ce plugin pour phonegap: https://build.phonegap.com/plugins/505

Et utilisez le paramètre correct comme ci-dessous pour contrôler la superposition de la vue Web:

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

Pour moi, avec Phonegap 3.3.0 cela fonctionne.

Plus d'informations, sur la page du projet Github: https://github.com/phonegap-build/StatusBarPlugin

xdemocle
la source
Merci beaucoup pour cette réponse !! J'essayais avec ce plugin: build.phonegap.com/plugins/715 , le problème est que les noms sont les mêmes. Mais ne fonctionne jamais pour moi. Merci beaucoup!!
Jabel Márquez
Pour être honnête, je ne me souviens pas si j'ai essayé avant celui-ci mentionné par vous.
xdemocle
20

Pour masquer la barre d'état, ajoutez le code suivant dans le fichier MainViewController.msous la fonction-(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
markmarijnissen
la source
Cela fait le travail. Il masquera la barre d'état rendant votre application en plein écran. Je n'ai testé cela que sur le simulateur, mais je ferai un rapport plus tard lorsque j'exécuterai une version sur mes iPhones et iPads.
Rob Evans
Fonctionne pour moi sur iOS sur un iPad 2
Mark Williams
Cela fonctionne bien sur iPad Air iOS 7.1.2 et aucun changement ou plug-in n'est nécessaire. Excellente réponse, merci!
Scriptlabs
Cela ignore totalement tout ce qu'Apple dit sur le `` mode plein écran immersif '' dans les directives de l'interface humaine ... ce n'est pas parce que vous utilisez un wrapper sur iOS que vous pouvez ignorer les modèles de conception ...: /
jesses .co.tt
15

Réponse https://stackoverflow.com/a/19249775/1502287 fonctionné pour moi, mais j'ai dû le changer un peu pour le faire fonctionner avec le plugin de caméra (et potentiellement d'autres) et une balise meta viewport avec "height = device- height "(ne pas régler la partie hauteur ferait apparaître le clavier sur la vue dans mon cas, masquant certaines entrées en cours de route).

Chaque fois que vous ouvrez la vue de la caméra et que vous revenez à votre application, la méthode viewWillAppear est appelée et votre vue diminue de 20 pixels.

En outre, la hauteur de l'appareil pour la fenêtre comprendrait les 20 pixels supplémentaires, ce qui rendrait le contenu défilable et 20px plus haut que la vue Web.

Voici la solution complète au problème de la caméra:

Dans MainViewController.h:

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

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

Maintenant, pour le problème de la fenêtre d'affichage, dans votre écouteur d'événements deviceready, ajoutez ceci (en utilisant 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');
}

Voici la fenêtre que j'utilise pour les autres versions:

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

Et tout fonctionne bien maintenant.

Dieppe
la source
Toute méthode sans Jquery @dieppe
Arjun T Raj
ajoutez simplement ce code à - (void) imagePickerController: (UIImagePickerController *) sélecteur didFinishPickingMediaWithInfo: (NSDictionary *) info {} méthode dans CDVCamera.m qui résout également le problème de la caméra. NSLog (@ "CAMÉRA FERMÉE"); [[UIApplication sharedApplication] setStatusBarHidden: OUI withAnimation: UIStatusBarAnimationNone];
Arjun T Raj
Mec, je ne connais pas les mots pour dire merci! J'ai eu du mal avec le problème de réduction de 20 pixels avec l'appareil photo, et je n'ai pas pu trouver la solution jusqu'à présent ...
Tuks
6

Essayez d'aller dans le (app name)-Info.plistfichier de l'application dans XCode et ajoutez les clés

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

Cela fonctionne pour moi sans problème.

dk123
la source
Pour moi, cela fonctionne dans le simulateur avec une version locale, mais pas dans l'iPad avec une version distante. Utilisation de PG 3.1 pour la construction et iOS7 sur le simulateur et l'iPad.
Per Quested Aronsson
@PerQuestedAronsson Vous voudrez peut-être essayer de le construire localement sur l'iPad. Je travaille sans problème avec un iPad iOS7 avec phonegap 3.1.
dk123
6

Pour Cordova 3.1+, il existe un plugin qui traite le changement de comportement de la barre d'état pour iOS 7+.

Ceci est bien documenté ici , y compris comment la barre d'état peut être rétablie dans son état pré-iOS7.

Pour installer le plugin, exécutez:

cordova plugin add org.apache.cordova.statusbar

Ajoutez ensuite ceci à config.xml

<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarStyle" value="default" />
piste0
la source
Vous pouvez également définir la couleur de StatusBar qui est par défaut le noir: <preference name = "StatusBarBackgroundColor" value = "# 000000" /> Voir: plugins.cordova.io/#/package/org.apache.cordova.statusbar
ezzadeen
2
Pour Cordova 5+, le plugin a été renommé: cordova plugin add cordova-plugin-statusbar
raider33
5

Je résous mon problème en installant le org.apache.cordova.statusbaret en ajoutant dans mon top config.xml:

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

Ces configurations ne fonctionnent que pour iOS 7+

Référence: http://devgirl.org/2014/07/31/phonegap-developers-guid/

mayconbelfort
la source
1

J'utilise le morceau de code suivant pour ajouter une classe au corps, si iOS7 est détecté. Je stylise ensuite cette classe pour ajouter une 20pxmarge en haut de mon conteneur. Assurez-vous que le plugin "device" est installé et que ce code est à l'intérieur de l'événement "deviceready".

En lisant, j'ai entendu dire que la prochaine mise à jour de Phonegap (3.1 je crois) prendrait mieux en charge les modifications apportées à la barre d'état d'iOS7. Cela peut donc être nécessaire comme solution à court terme.

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

Une autre façon est de rétrocompatible . Créez le code HTML selon iOS 7(avec une marge supplémentaire de 20 pixels en haut) pour donner cet full screenaspect et réduire cette marge supplémentaire iOS < 7.0. Quelque chose comme ce qui suit dans 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;
  }
}

Cette solution ne laissera pas de barre noire sur le dessus iOS 7.0et au-dessus, ce qu'un utilisateur iOS moderne trouvera étrange et ancien .

tipycalFlow
la source
0

Écrivez le code suivant dans AppDelegate.m dans l' événement didFinishLaunchingWithOptions (exactement avant sa dernière ligne de code " return YES; "):

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

J'attendrai vos retours! :)

Ehsan
la source
Ce code semble fonctionner très bien pour masquer la barre d'état et résoudre le problème, j'ai également regardé un peu hier et j'ai trouvé une paix de code qui a essentiellement redimensionné l'UIWebView et l'a déplacé vers le
bas.J'ai également
C'est génial. Mon code n'utilise qu'un moyen simple et facile de le faire! Nous faisons tous la même chose avec des méthodes différentes :)
Ehsan
0

si nous utilisons le plug-in de caméra pour la galerie d'images, la barre d'état reviendra.Pour résoudre ce problème, veuillez ajouter cette ligne

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

à

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

fonction à l'intérieur de CVDCamera.m dans la liste des plugins

Arjun T Raj
la source
0

Écrivez le code suivant dans AppDelegate.m dans l' événement didFinishLaunchingWithOptions au démarrage.

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

Et corrigez pour les versions supérieures à iOS 7 et supérieures.

RahulSalvikar
la source
0

Pour garder la barre d'état visible en portrait mais la masquer en paysage (c'est-à-dire en plein écran), essayez ce qui suit:

Dans MainViewController.h:

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

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

C'est une combinaison de ce que j'ai trouvé dans cette discussion et des discussions liées à StackOverflow, du code du plugin Cordova StatusBar (pour ne pas coder en dur la valeur 20px), et quelques incantations de ma part (je ne suis pas un développeur iOS donc J'ai tâtonné mon chemin vers cette solution).

matb33
la source
0

Tout d'abord, ajoutez le plugin Device dans votre projet. L'ID du plug-in est: org.apache.cordova.device et le référentiel est: https://github.com/apache/cordova-plugin-device.git

Ensuite, utilisez cette fonction et appelez-la sur chaque page ou écran: -

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
la source
0

La meilleure façon de contrôler l'arrière-plan de la barre d'état - 2017

Après une frustration continue, de nombreuses recherches sur Internet, voici les étapes à suivre:

  1. Assurez-vous que vous utilisez le plugin de barre d'état
  2. Ajoutez ce paramètre à votre config.xml:

<préférence name = "StatusBarOverlaysWebView" value = "false" />

  1. Utilisez le code suivant sur onDeviceReady

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

Cela fonctionne pour moi sous iOS et Android.

Bonne chance!

Niv Asraf
la source