iOS 7 Status bar with Phonegap

64,463

Solution 1

I found an answer on another thread, but I'll answer the question in case someone else wonders.

Just replace the viewWillAppear in MainViewController.m with this:

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

Solution 2

In addition to Ludwig Kristoffersson's resize fix, I recommend changing status bar color:

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

Solution 3

please, install that plugin for phonegap: https://build.phonegap.com/plugins/505

And use the correct setting like below, to control the overlay of the webview:

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

For me, with Phonegap 3.3.0 it works.

More information, on the Github project page: https://github.com/phonegap-build/StatusBarPlugin

Solution 4

To hide statusbar, add the following code in the file MainViewController.m under the function -(void)viewDidUnload

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Solution 5

Answer https://stackoverflow.com/a/19249775/1502287 worked for me, but I had to change it a bit to make it work with the camera plugin (and potentially others) and a viewport meta tag with "height=device-height" (not setting the height part would cause the keyboard to appear over the view in my case, hiding some inputs along the way).

Each time you would open the camera view and go back to your app, the viewWillAppear method would be called, and your view would shrink by 20px.

Also, the device-height for the viewport would include the 20 extra px, rendering the content scrollable and 20px higher than the webview.

Here is the complete solution for the camera problem:

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

Now for the viewport problem, in your deviceready event listener, add this (using 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).
        // I don't know if it is 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');
}

Here is the viewport I use for other versions:

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

And all works well now.

Share:
64,463
Luddig
Author by

Luddig

Updated on July 11, 2022

Comments

  • Luddig
    Luddig almost 2 years

    In iOS 7, Phonegap applications will appear underneath the status bar. This can make it difficult to click on buttons/menus that have been placed at the top of the screen.

    Is there someone who knows a way to fix this status bar issue on iOS 7 in a Phonegap application?

    I've tried to offset the entire web page with CSS but it doesn't seem to work. Is there a way to like offset the entire UIWebView or just make the status bar behave like it did in iOS6?

    Thanks

  • Luddig
    Luddig over 10 years
    This code looks to work great to hide the status bar and fix the issue, i also looked around a bit yesterday and found a peace of code that essentially resized the UIWebView and moved it down I added this as an answer as well :)
  • Ehsan
    Ehsan over 10 years
    That's great. My code is only using a simple and easy way for doing it! All of us are doing the same thing with different methods :)
  • Paul
    Paul over 10 years
    Is anyone else using this with the In App Browser plugin? If I configure the In App Browser as "presentationstyle=fullscreen", a blank bottom margin is appearing after the browser is closed. It looks like the margin is the same height as the InAppBrowser toolbar. Setting the presentationtype to "pagesheet" fixes this on iPad, but iPhone seems to always use "fullscreen". Any workarounds?
  • Michael
    Michael over 10 years
    Very grateful for the answer -- however the same issue applies to the PhoneGap inApp browser -- it overlays the status bar as well. Any ideas for that?
  • Arjun T Raj
    Arjun T Raj over 10 years
    Any method without Jquery @dieppe
  • Arjun T Raj
    Arjun T Raj over 10 years
    simply add this code to - (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info {} method inside CDVCamera.m that solves camera issue also. NSLog(@"CLOSED CAMERA"); [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
  • hnilsen
    hnilsen over 10 years
    Yes, we use an older version of Cordova (2.3.0), and to fix this you'll have to set webViewBounds.origin.y = 20; in createViewsWithOptions. Also, see if the background color is being set and play around with that. Do a version check for iOS7 and above, just as in this excellent answer from LudWig Kristoffersson.
  • hnilsen
    hnilsen over 10 years
    Also - if you're using the InAppBrowser, the view will re-initialize each time you return. So it would be prudent to add a flag that says it's already been run to your MainViewController.m.
  • Chris Karcher
    Chris Karcher over 10 years
    Because this code runs in viewWillAppear, you'll run into issues with this solution if your PhoneGap/Cordova app displays other native views (like the camera capture dialog) and returns to this view. The fix for me was to initialize 'viewBounds' to '[self.view bounds]' instead of '[self.webView bounds]'.
  • Carlos G.
    Carlos G. over 10 years
    by the way I did have an issue with the InAppBrowser, explain in the first comment here. and I applied the recommendation from Chris Karcher above. that worked for me. So thank you. regards,
  • rkaartikeyan
    rkaartikeyan over 10 years
    Working Great :) Thanks a Lot :)
  • Per Quested Aronsson
    Per Quested Aronsson over 10 years
    For me, this works in the simulator with a local build, but not in the iPad with a remote build. Using PG 3.1 for the build and iOS7 on the simulator and the iPad.
  • dk123
    dk123 over 10 years
    @PerQuestedAronsson You might want to try building it locally on to the iPad. I'm working with an iPad iOS7 with phonegap 3.1 without problem.
  • Rob Evans
    Rob Evans over 10 years
    This does the job. It will hide the statusbar making your app full screen. I only tested this on the simulator but will report back later when I run a build on my iPhones and iPads.
  • David Daudelin
    David Daudelin about 10 years
    Perfect - this was the better solution for me.
  • Sampsa
    Sampsa about 10 years
    Shouldn't it actually be - 40 px to viewBounds.size.height in order to compensate the lost pixels? Without this the bottom of page is not visible.
  • bmurmistro
    bmurmistro about 10 years
    I ran into the same thing Chris did. I just put the solution in webViewDidFinishLoad... that way it only gets called once. When I had it in viewWillAppear, the height of the view would shrink 20 pixels every time I tried to use the camera.
  • leech
    leech about 10 years
    This will make the view shrink every time the camera is used.
  • DemitryT
    DemitryT about 10 years
    This fix works locally after an Xcode build, but not after I do a phonegap build. Any ideas? I have an ios app built with phonegap 2.9
  • Mark Williams
    Mark Williams about 10 years
    Works for me on iOS on an iPad 2
  • Jabel Márquez
    Jabel Márquez almost 10 years
    Thanks a lot for this answer!! I was trying with this plugin: build.phonegap.com/plugins/715 , the problem is that names are the same. But never works for me. Thanks a lot!!
  • xdemocle
    xdemocle almost 10 years
    To be honest, I don't remember if I tried before this one mentioned by you.
  • Austin France
    Austin France almost 10 years
    I just moved the whole code into viewDidLoad after calling [super viewDidLoad] and it seems to be working perfectly even after popping out to camera and back.
  • magorich
    magorich almost 10 years
    This solution works but I had a problem with fullscreen videos and I found this other one and it fixed my problem zsprawl.com/iOS/2013/10/fixing-the-phonegap-status-bar-in-‌​ios7
  • magorich
    magorich almost 10 years
  • gregdevs
    gregdevs almost 10 years
    Thanks so much, this is working for me using latest PG.
  • Scriptlabs
    Scriptlabs over 9 years
    This works fine on iPad Air iOS 7.1.2 and there is no need for any changes or plugins. Great answer, thank you!
  • Mirko
    Mirko over 9 years
    The problem I have with this is when navigating back I have to scroll down because my pages are 20px up...
  • tuks
    tuks over 9 years
    Man, I don't know the words to say thank you! I've been struggling with the 20px shrink problem with camera, and couldn't find the solution until now...
  • Umair
    Umair over 9 years
    Thanks. It worked as expected. Is there a way I can change the color of status bar? It's currently showing as white. (I'm not an iOS developer so code samples will be more than welcome.) Thanks
  • Kirankumar Sripati
    Kirankumar Sripati over 9 years
    @magorich I tried it, but it hides bottom 20px of screen
  • magorich
    magorich over 9 years
    @KirankumarSripati actually my last solution was this I hope thiw works for you 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; } I did that because my app was resizing everytime I entered fullscreen
  • SURESH SANKE
    SURESH SANKE over 9 years
    Fantastic boss. Nice solution for us.Thanks a lotttt
  • ezzadeen
    ezzadeen over 9 years
    You can also set the StatusBar color which defaults to black: <preference name="StatusBarBackgroundColor" value="#000000" /> See: plugins.cordova.io/#/package/org.apache.cordova.statusbar
  • jesses.co.tt
    jesses.co.tt about 9 years
    This totally ignores everything that Apple says about 'immersive fullscreen mode" in the Human Interface Guidelines... just because you're using a wrapper on top of iOS doesn't mean you can ignore the design patterns... :/
  • raider33
    raider33 over 8 years
    For Cordova 5+, the plugin has been renamed: cordova plugin add cordova-plugin-statusbar