Pasek stanu iOS 7 z Phonegap

91

W systemie iOS 7 aplikacje Phonegap pojawią się pod paskiem stanu. Może to utrudniać klikanie przycisków / menu, które zostały umieszczone u góry ekranu.

Czy jest ktoś, kto wie, jak rozwiązać ten problem z paskiem stanu w systemie iOS 7 w aplikacji Phonegap?

Próbowałem zrównoważyć całą stronę internetową za pomocą CSS, ale wydaje się, że nie działa. Czy istnieje sposób, aby polubić przesunięcie całego UIWebView lub po prostu sprawić, aby pasek stanu zachowywał się tak, jak w iOS6?

Dzięki

Luddig
źródło
czym dokładnie jest „problem z paskiem stanu”? Jakiś przykładowy kod do odtworzenia?
Raptor
1
@ShivanRaptor W systemie iOS 7 pasek stanu jest teraz częścią widoku, więc jeśli masz rzeczy, które znajdowały się na górze ekranu w poprzednich wersjach iOS, znajduje się teraz pod paskiem stanu, a nie jest automatycznie przesuwany tuż pod nim, co może powodować pewne problemy. Moją sugestią byłoby utworzenie opakowania dla treści i ustawienie górnego marginesu na 20 pikseli.
Andrew Lively,
@AndrewLively - To tak naprawdę nie działa, gdy strona jest przewijana, czy istnieje sposób na przeniesienie UIWebView?
Luddig

Odpowiedzi:

143

Znalazłem odpowiedź w innym wątku, ale odpowiem na pytanie na wypadek, gdyby ktoś inny się zastanawiał.

Po prostu zamień viewWillAppearw MainViewController.mto:

- (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
źródło
9
Czy ktoś jeszcze używa tego z wtyczką In App Browser? Jeśli skonfiguruję przeglądarkę w aplikacji jako „styl prezentacji = pełny ekran”, po zamknięciu przeglądarki pojawi się pusty dolny margines. Wygląda na to, że margines ma taką samą wysokość jak pasek narzędzi InAppBrowser. Ustawienie typu prezentacji na „arkusz stron” rozwiązuje ten problem na iPadzie, ale iPhone wydaje się zawsze używać „pełnego ekranu”. Jakieś obejścia?
Paul
1
Bardzo wdzięczny za odpowiedź - jednak ten sam problem dotyczy przeglądarki PhoneGap inApp - nakłada się ona również na pasek stanu. Jakieś pomysły na to?
Michael
2
Tak, używamy starszej wersji Cordova (2.3.0) i aby to naprawić, musisz ustawić webViewBounds.origin.y = 20; w createViewsWithOptions. Sprawdź także, czy ustawiany jest kolor tła i baw się z tym. Sprawdź wersję dla iOS7 i nowszych wersji, tak jak w tej doskonałej odpowiedzi LudWiga Kristofferssona.
hnilsen
3
Ponadto - jeśli używasz InAppBrowser, widok zostanie ponownie zainicjowany za każdym razem, gdy wrócisz. Dlatego rozsądnie byłoby dodać flagę, która mówi, że została już uruchomiona do pliku MainViewController.m.
hnilsen
14
Ponieważ ten kod działa w viewWillAppear, napotkasz problemy z tym rozwiązaniem, jeśli aplikacja PhoneGap / Cordova wyświetla inne natywne widoki (takie jak okno dialogowe przechwytywania aparatu) i wraca do tego widoku. Rozwiązaniem dla mnie było zainicjowanie „viewBounds” na „[self.view bounds]” zamiast „[self.webView bounds]”.
Chris Karcher
37

Oprócz poprawki zmiany rozmiaru autorstwa Ludwiga Kristofferssona zalecam zmianę koloru paska stanu:

- (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.
źródło
1
Działa świetnie :) Wielkie dzięki :)
rkaartikeyan
Idealnie - to było dla mnie lepsze rozwiązanie.
David Daudelin
Ta poprawka działa lokalnie po kompilacji Xcode, ale nie po wykonaniu kompilacji phonegap. Jakieś pomysły? Mam aplikację na iOS zbudowaną za pomocą phonegap 2.9
DemitryT
To rozwiązanie działa, ale miałem problem z filmami pełnoekranowymi i znalazłem ten drugi i naprawił mój problem zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-ios7
magorich
1
@KirankumarSripati właściwie moim ostatnim rozwiązaniem było to. Mam nadzieję, że thiw działa dla ciebie NSInteger screenSize = 0; // Globalne 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; } Zrobiłem to, ponieważ moja aplikacja
zmieniała
22

proszę, zainstaluj tę wtyczkę do phonegap: https://build.phonegap.com/plugins/505

I użyj prawidłowego ustawienia, jak poniżej, aby kontrolować nakładkę widoku internetowego:

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

U mnie z Phonegap 3.3.0 to działa.

Więcej informacji na stronie projektu Github: https://github.com/phonegap-build/StatusBarPlugin

xdemocle
źródło
Wielkie dzięki za tę odpowiedź !! Próbowałem z tą wtyczką: build.phonegap.com/plugins/715 , problem polega na tym, że nazwy są takie same. Ale dla mnie nigdy nie działa. Wielkie dzięki!!
Jabel Márquez
Szczerze mówiąc, nie pamiętam, czy próbowałem przed tym wspomnianym przez Ciebie.
xdemocle
20

Aby ukryć pasek stanu, dodaj następujący kod w pliku MainViewController.mpod funkcją-(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}
markmarijnissen
źródło
To spełnia swoje zadanie. Spowoduje to ukrycie paska stanu, czyniąc aplikację na pełnym ekranie. Przetestowałem to tylko na symulatorze, ale wrócę później, gdy uruchomię kompilację na moich iPhone'ach i iPadach.
Rob Evans,
U mnie działa na iOS na iPadzie 2
Mark Williams
Działa to dobrze na iPadzie Air iOS 7.1.2 i nie ma potrzeby wprowadzania żadnych zmian ani wtyczek. Świetna odpowiedź, dziękuję!
Scriptlabs
To całkowicie ignoruje wszystko, co Apple mówi o „wciągającym trybie pełnoekranowym” w Wytycznych dotyczących interfejsu ludzkiego ... tylko dlatego, że używasz opakowania na iOS, nie oznacza to, że możesz ignorować wzorce projektowe ...: /
jesses .co.tt
15

Odpowiedź https://stackoverflow.com/a/19249775/1502287 działała dla mnie, ale musiałem to trochę zmienić, aby działała z wtyczką aparatu (i potencjalnie innymi) i metatagiem widoku z „height = device- wysokość ”(brak ustawienia części wysokości spowodowałoby pojawienie się klawiatury nad widokiem w moim przypadku, ukrywając niektóre wejścia po drodze).

Za każdym razem, gdy otwierasz widok kamery i wracasz do aplikacji, wywoływana jest metoda viewWillAppear, a widok zmniejsza się o 20 pikseli.

Ponadto wysokość urządzenia dla widocznego obszaru obejmowałaby dodatkowe 20 pikseli, renderujące zawartość przewijalną i o 20 pikseli wyższe niż widok sieciowy.

Oto kompletne rozwiązanie problemu z aparatem:

W MainViewController.h:

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

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

Teraz, jeśli chodzi o problem z widocznym obszarem, w odbiorniku zdarzeń urządzenia gotowego do dodania (używając 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');
}

Oto rzutnia, którego używam w innych wersjach:

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

I teraz wszystko działa dobrze.

dieppe
źródło
Dowolna metoda bez Jquery @dieppe
Arjun T Raj
po prostu dodaj ten kod do - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {} metody wewnątrz CDVCamera.m, która również rozwiązuje problem z kamerą. NSLog (@ "ZAMKNIĘTA KAMERA"); [[UIApplication sharedApplication] setStatusBarHidden: YES withAnimation: UIStatusBarAnimationNone];
Arjun T Raj
Człowieku, nie znam słów, żeby ci powiedzieć, dziękuję! Zmagałem się z problemem zmniejszania rozmiaru 20px z kamerą i do tej pory nie mogłem znaleźć rozwiązania ...
tuks
6

Spróbuj wejść do (app name)-Info.plistpliku aplikacji w XCode i dodaj klucze

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

U mnie to działa bez problemu.

dk123
źródło
U mnie działa to w symulatorze z kompilacją lokalną, ale nie w iPadzie z kompilacją zdalną. Używanie PG 3.1 do kompilacji i iOS7 na symulatorze i iPadzie.
Per Quested Aronsson
@PerQuestedAronsson Możesz spróbować zbudować go lokalnie na iPadzie. Pracuję z iPadem iOS7 z phonegap 3.1 bez problemu.
dk123
6

W przypadku Cordova 3.1+ dostępna jest wtyczka, która radzi sobie ze zmianą zachowania paska stanu w iOS 7+.

Jest to ładnie udokumentowane tutaj , w tym, jak można przywrócić pasek stanu do stanu sprzed iOS7.

Aby zainstalować wtyczkę, uruchom:

cordova plugin add org.apache.cordova.statusbar

Następnie dodaj to do config.xml

<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarStyle" value="default" />
track0
źródło
Możesz także ustawić kolor paska stanu, który domyślnie jest czarny: <preference name = "StatusBarBackgroundColor" value = "# 000000" /> Zobacz: plugins.cordova.io/#/package/org.apache.cordova.statusbar
ezzadeen
2
W przypadku Cordova 5+ nazwa wtyczki została zmieniona: wtyczka Cordova dodaj cordova-plugin-
statusbar
5

Rozwiązuję swój problem instalując org.apache.cordova.statusbari dodając w moim topie config.xml:

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

Te konfiguracje działają tylko na iOS 7+

Źródła: http://devgirl.org/2014/07/31/phonegap-developers-guid/

mayconbelfort
źródło
1

Używam następującego fragmentu kodu, aby dodać klasę do treści, jeśli zostanie wykryty iOS7. Następnie nadaję tej klasie styl, aby dodać 20pxmargines na górze mojego kontenera. Upewnij się, że masz zainstalowaną wtyczkę „device” i że ten kod znajduje się w zdarzeniu „deviceready”.

Po przeczytaniu dowiedziałem się, że następna aktualizacja Phonegap (wydaje mi się, że 3.1) będzie lepiej obsługiwać zmiany w pasku stanu iOS7. Może to być potrzebne tylko jako rozwiązanie krótkoterminowe.

if(window.device && parseFloat(window.device.version) >= 7){
  document.body.classList.add('fix-status-bar');
}
Ryan
źródło
1

Innym sposobem jest przywrócenie kompatybilności wstecznej . Utwórz kod HTML zgodnie z iOS 7(z dodatkowym marginesem 20 pikseli na górze), aby nadać temu full screenwyglądowi i odciąć ten dodatkowy margines iOS < 7.0. Coś takiego w 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;
  }
}

To rozwiązanie nie pozostawi czarnego paska na górze iOS 7.0i powyżej, co współczesny użytkownik iOS uzna za dziwne i stare .

tipycalFlow
źródło
0

Napisz następujący kod wewnątrz AppDelegate.m w zdarzeniu didFinishLaunchingWithOptions (dokładnie przed ostatnim wierszem kodu „ return YES; ”):

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

Czekam na twoją opinię! :)

Ehsan
źródło
Wygląda na to, że ten kod świetnie działa, aby ukryć pasek stanu i rozwiązać problem, rozejrzałem się też trochę wczoraj i znalazłem spokój kodu, który zasadniczo zmienił rozmiar UIWebView i przesunął go w dół Dodałem to również jako odpowiedź :)
Luddig
To wspaniale. Mój kod wykorzystuje do tego prosty i łatwy sposób! Wszyscy robimy to samo z różnymi metodami :)
Ehsan
0

jeśli użyjemy wtyczki aparatu do galerii obrazów, pasek stanu wróci, więc aby rozwiązać ten problem, dodaj tę linię

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

do

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

funkcja wewnątrz CVDCamera.m na liście wtyczek

Arjun T Raj
źródło
0

Napisz następujący kod wewnątrz AppDelegate.m w zdarzeniu didFinishLaunchingWithOptions podczas uruchamiania.

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

I naprawiono powyżej iOS 7 i nowsze.

RahulSalvikar
źródło
0

Aby pasek stanu był widoczny w orientacji pionowej, ale ukrył go w orientacji poziomej (tj. Na pełnym ekranie), spróbuj wykonać następujące czynności:

W MainViewController.h:

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

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

Jest to kombinacja tego, co znalazłem w tej i połączonych dyskusjach StackOverflow, trochę kodu z wtyczki Cordova StatusBar (aby nie zakodować na stałe wartości 20px) i niektórych zaklęć z mojej strony (nie jestem programistą iOS, więc Po omacku ​​doszedłem do tego rozwiązania).

matb33
źródło
0

Przede wszystkim dodaj wtyczkę Device w swoim projekcie. Identyfikator wtyczki to: org.apache.cordova.device, a repozytorium to: https://github.com/apache/cordova-plugin-device.git

Następnie użyj tej funkcji i wywołaj ją na każdej stronie lub ekranie: -

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
źródło
0

Najlepszy sposób na kontrolowanie tła paska stanu - 2017

Po ciągłej frustracji, wielu poszukiwaniach w Internecie, oto kroki, które musisz wykonać:

  1. Upewnij się, że używasz wtyczki paska stanu
  2. Dodaj to ustawienie do pliku config.xml:

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

  1. Użyj poniższego kodu w onDeviceReady

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

Działa na mnie w iOS i Androidzie.

Powodzenia!

Niv Asraf
źródło