49
votes

I recently upgraded to xcode 5 and when I run my app in the iOS simulator the splash screen overlaps the status bar and when you are in the app the status bar overlaps onto elements on my app, like a back button I have on the top left hand corner of my app. I build my app using phonegap 2.9. Any ideas how i can get this to render correctly.

splashscreen

UI

25
Hm. Isn't it the same problem solved here? stackoverflow.com/questions/17763719/status-bar-wont-disappearice.cube

25 Answers

67
votes

You can resolve this issue if you are using storyboards, as in this question: iOS 7 - Status bar overlaps the view

If you're not using storyboard, then you can use this code in your AppDelegate.m in did finishlaunching:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
    [application setStatusBarStyle:UIStatusBarStyleLightContent];
    self.window.clipsToBounds =YES;
    self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
}

Also see this question: Status bar and navigation bar issue in IOS7

50
votes

In MainViewController.m inside: - (void)viewWillAppear:(BOOL)animated add this:

//Lower screen 20px on ios 7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 18;
        viewBounds.size.height = viewBounds.size.height - 18;
        self.webView.frame = viewBounds;
    }

so the end function will look like 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 = 18;
        viewBounds.size.height = viewBounds.size.height - 18;
        self.webView.frame = viewBounds;
    }
    [super viewWillAppear:animated];
}
36
votes

What I usually do is add two key-value properties to the Info.plist file.

enter image description here

The properties source code is:

enter image description here

9
votes

I've got a problem opening the inApp browser with phonegap. Gimi's fix worked well, but everytime I opened the inApp browser the screen was shrinked at the bottom. So I've added an if statement to check if the webview's y origin was 0. The inApp browser hasn't the y origin 0 anymore so it solved my problem.

// ios 7 status bar fix
- (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) {
        if(self.webView.frame.origin.y == 0) {
            CGRect viewBounds = [self.webView bounds];
            viewBounds.origin.y = 20;
            viewBounds.size.height = viewBounds.size.height - 20;
            self.webView.frame = viewBounds;
        }
    }

    [super viewWillAppear:animated];
}

The solution is not really mine but I can't find the source. Hope it helps!

6
votes

Place this code snippet in your MainViewController.m file in the phonegap project.

- (void)viewDidLayoutSubviews{

    if ([self respondsToSelector:@selector(topLayoutGuide)]) // iOS 7 or above
    {
        CGFloat top = self.topLayoutGuide.length;
        if(self.webView.frame.origin.y == 0){
            // We only want to do this once, or 
            // if the view has somehow been "restored" by other    code.
            self.webView.frame = CGRectMake(self.webView.frame.origin.x,
                                           self.webView.frame.origin.y + top,
                                           self.webView.frame.size.width,
                                           self.webView.frame.size.height-top);
        } 
    } 
}
5
votes

I use this code in the ViewDidLoad method.

 if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
 {
    self.edgesForExtendedLayout = UIRectEdgeNone;
 }

This works when trying to support previous iOS versions too.

5
votes

Actually, I found Gimi's answer to be the best answer, and I've been looking a lot! Just to add to Gimi's answer, and also answer ignacio-munizaga's reply on that answer, The code will execute whenever the view appears, which means after you close an inline browser, or after camera roll etc. so I just put a bool value stating whether the size has already been adjusted.

The final code looks like:

bool sizeWasAdjusted = false;
- (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 (!sizeWasAdjusted && [[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        CGRect viewBounds = [self.webView bounds];
        viewBounds.origin.y = 18;
        viewBounds.size.height = viewBounds.size.height - 18;
        self.webView.frame = viewBounds;
        sizeWasAdjusted = true;
    }
    [super viewWillAppear:animated];
}
5
votes

Try going into the app's (app name)-Info.plist file in XCode and add the key

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

This seems to work for me without problem.

5
votes

If your developing for iOS 7 I wouldn't recommend wrapping the status bar in a black rectangle old iOS style. Just integrate it to the design for a more iOS 7 "fullscreen" look.

You can use this plugin to adjust the ink colour of the status bar, or hide it or show it in any instance of your app.

https://github.com/jota-v/cordova-ios-statusbar

The js methods are:

window.plugins.statusBar.hide();
window.plugins.statusBar.show();
window.plugins.statusBar.blackTint();
window.plugins.statusBar.whiteTint();

IMPORTANT: Also in your app plist file set UIViewControllerBasedStatusBarAppearance to NO.

4
votes

Better to have this things in info.plist

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

this makes no status bar at all.

3
votes

To address the issue of the status bar iOS7, we can use the following code to Cordova / PhoneGap:

function onDeviceReady() {
    if (parseFloat(window.device.version) === 7.0) {
          document.body.style.marginTop = "20px";
    }
}

document.addEventListener('deviceready', onDeviceReady, false);

Anyway Cordova 3.1 will soon fix that this and other issues for iOS7.

3
votes
 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {

        self.window.clipsToBounds =YES;
[application setStatusBarStyle:UIStatusBarStyleLightContent];
 self.window.frame =  CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
    }
3
votes

From Apple iOS7 transition Guide,

Specifically,

self.automaticallyAdjustsScrollViewInsets = YES;
self.edgesForExtendedLayout = UIRectEdgeNone;

works for me when I don't want to overlap and I have a UITableViewController.

2
votes

If you're using Cordova with Sencha Touch and you're using the normal Sencha Touch navigation/title bars, you can just stretch the navbar and reposition the content within the navbar so it looks at home on iOS 7. Just add this into app.js (after your last Ext.Viewport.add line) :

// Adjust toolbar height when running in iOS to fit with new iOS 7 style
if (Ext.os.is.iOS && Ext.os.version.major >= 7) {
  Ext.select(".x-toolbar").applyStyles("height: 62px; padding-top: 15px;");
}

(Source: http://lostentropy.com/2013/09/22/ios-7-status-bar-fix-for-sencha-touch-apps/)

This is a bit hacky, I know, but it saves dealing with it at the Objective-C level. It won't be much good for those not using Sencha Touch with Cordova, though.

2
votes

Write the following code inside AppDelegate.m in didFinishLaunchingWithOptions event (exactly before its last line of code "return YES;" ) :

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

I'll wait for your feedback! :)

2
votes

In .plist file set property:

<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

It hides the statusBar.

1
votes

The best approach you can use, is to resize the main view, specially if your application uses a footer.

on MainViewController.m using the viewDidLoad method, after [super viewDidLoad];

NSArray *vComp = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
if ([[vComp objectAtIndex:0] intValue] >= 7) {
    // iOS 7 or above
    CGRect oldBounds = [self.view bounds];
    CGRect newViewBounds = CGRectMake( 0, -10, oldBounds.size.width, oldBounds.size.height-20 );
    CGRect newWebViewBounds = CGRectMake( 0, -20, oldBounds.size.width, oldBounds.size.height-40 );

    [self.view setBounds:newViewBounds];
    [self.webView setBounds:newWebViewBounds];
}

then you won't need to modify any javascript into your application

1
votes

With the release of iOS 7.0.4, the iOS7 fix broke in my current project, as 7.0.4 works w/o the fix. So added a minor control to just run it if running minor release 3 or less.

NSArray *vComp = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
if ([[vComp objectAtIndex:0] intValue] == 7 && [[vComp objectAtIndex:1] intValue] == 0 && [[vComp      objectAtIndex:2] intValue] <= 3 ) {
    CGRect oldBounds = [self.view bounds];
    CGRect newViewBounds = CGRectMake( 0, -10, oldBounds.size.width, oldBounds.size.height-20 );
    CGRect newWebViewBounds = CGRectMake( 0, -20, oldBounds.size.width, oldBounds.size.height-40 );
    [self.view setBounds:newViewBounds];
    [self.webView setBounds:newWebViewBounds];
}
1
votes

I started to go this route, but I have my own navigation control with a core view that I slide into a frame that's usually wrapping the core with a common title bar and tabbar; no storyboard, no UINavigationController.

It started to get complicated fast, adding and subtracting the 20 pixels of the status bar. Then an epiphany.

I made a copy of the .xib file, told Xcode to show it to me as an iOS 7 layout, realigned everything, and put a single 6/7 switch in code .. instantly, everything works right, and the additional resources add only 8K to the bundle.

0
votes

I develop for iOS7 first but in order to keep compatible with iOS6 I do exactly the opposite what Gimi suggested - in MainViewController.m I set the y origin 20px up and increase the view height by 20px:

//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;
}
0
votes

We can also check this within our js files

if (parseFloat(window.device.version) >= 7.0) {

    $("body").addClass("ios7");
}

In .css file define a class for this

 .ios7 .ui-page, .ios7 .ui-header, .ios7 .ui-pane {
     margin-top: 17px !important;
  }
0
votes

Some of the above answers will give you a black bar on top if you set your screen bound 20px, other will keep reduce your webview screen if you use webview.frame.size.height -20px; Try this one then, it works on any ios and no need to change css, put in inside

- (void)webViewDidFinishLoad:(UIWebView*)theWebView {

//is it IOS7 and up

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {

//get the device screen size

    CGRect screenBounds = [[UIScreen mainScreen] bounds];

//reduce the height by 20px

    int x= screenBounds.size.height -20;

//set the webview top pos 20px so it is under the status bar and reduce the size by 20px

    [theWebView setFrame:CGRectMake(0, 20, theWebView.frame.size.width, x )];

}
0
votes

For iPhoneX

For all the answers above :

The height of the status bar in the iPhoneX is 44 and not 20

-1
votes

Here is my approach using CSS and Javascript:

1) Define the following in your CSS:

#ios7-statusbar-fix {
    width:100%;
    height:20px;
    background-color:white;
    position:fixed;
    z-index:10000;
    margin-top:-20px;
    display:none;
}

2) Add div-container with this id as very first element after your <body>-tag:

<body>
    <div id="ios7-statusbar-fix"></div>
…

3) Filter iOS 7 devices and apply changes via Javascript:

if (navigator.userAgent.match(/(iPad.*|iPhone.*|iPod.*);.*CPU.*OS 7_\d/i)) {
        document.body.style.marginTop = '20px';
        document.getElementById('ios7-statusbar-fix').style.display = 'block';
}
-2
votes

Many thanks man. It worked fine on:

MAC OS X 10.9.1 - Xcode 5.0.2 - cordova 3.3 - jQuery mobile 1.3.2.