49

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

Irfan
  • 4,301
  • 6
  • 29
  • 46
Automator21
  • 647
  • 2
  • 7
  • 11
  • 2
    Hm. Isn't it the same problem solved here? http://stackoverflow.com/questions/17763719/status-bar-wont-disappear – ice.cube Sep 19 '13 at 04:59

25 Answers25

67

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

Community
  • 1
  • 1
Romance
  • 1,416
  • 11
  • 21
  • Thank you that worked. Is it supposed to just display a black bar or can the time, battery icon be displayed like it would be in iOS6? – Automator21 Sep 19 '13 at 05:31
  • 7
    Hey My status bar portion is not visible. Its Balck using this code. can u help me why? – Sahil Mahajan Sep 30 '13 at 07:52
  • Status bar is not visible anymore with this trick, but this is really not a problem at all. Works great, thanks! – plang Oct 03 '13 at 06:48
  • You can use this link also http://stackoverflow.com/questions/18980925/status-bar-issue-and-navigation-bar-issue-in-ios7/19025547#19025547 – Romance Oct 03 '13 at 06:50
  • self.window.frame.size were null for me, so I had to use: CGRect screenBounds = [[UIScreen mainScreen] bounds]; screenBounds.size.width; Also, for landscape orientation the last line looked like this: self.window.frame = CGRectMake(20,0,screenBounds.size.width-20,screenBounds.size.height); – Fadi Oct 11 '13 at 16:37
  • I tried this and found that modifying window frame this way causes visual bug on some UI, e.g. UIActionSheet. Screenshot -> http://cl.ly/image/0Z2W2n0A2W0o – Hlung Dec 01 '13 at 16:37
  • If I use this code I'm having problem with MFMailComposeViewController. The view again moving up. any idea? – Ganesh G Dec 13 '13 at 08:55
  • Ganesh try to follow this url http://stackoverflow.com/questions/18980925/status-bar-and-navigation-bar-issue-in-ios7/19025547#19025547 . It will be sort out your problem ,my code will be usefull only when there will not have any other window while application is running - @G.Ganesh – Romance Dec 13 '13 at 09:58
  • @Romance, Thank you. I solved my problem before I was asking you by the url that you shared. But I thought that you have any other solution. Anyway thank you for responding. – Ganesh G Dec 17 '13 at 11:24
  • great answer. worked like charm in my phonegap application too. – sac May 09 '14 at 12:21
50

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];
}
Gimi
  • 600
  • 3
  • 3
  • 4
    This is the best solution for a phonegap/cordova app. Minor nitpick - should you be using 20 rather than 18 ? – asgeo1 Oct 05 '13 at 05:06
  • I tried my app with 20, and i could still see 2 pixels between the status bar and and fixed element when scrolling inside the app. You can use 20 if it works for you. – Gimi Oct 06 '13 at 03:05
  • 1
    This has a problem with inAppBrowser. When closing a webpage opened with inAppBrowser, you get a 18px white bar a the bottom. ¿Is there any solution to this? – ignacio.munizaga Oct 15 '13 at 20:24
  • 12
    I ran into the same problem as Ignacio where a white bar was displayed at the bottom of my app after showing another native view (e.g. the camera capture dialog) and then navigating back to the webView. The white bar would grow every time the second native dialog was shown/dismissed. The fix was to initialize 'viewBounds' to '[self.view bounds]' instead of '[self.webView bounds]'. – Chris Karcher Nov 27 '13 at 01:54
  • 1
    I love you - 3 days of wasted tinkering to fix this issue. Other solutions had issues with device rotation and would clip my app's content. This IS the best PhoneGap solution! – tylerl Dec 08 '13 at 16:31
  • 1
    If you're having problem with scrollbars in PhoneGap after setting this, make sure you've removed `height=device-height` from ``. – Jan Dudek Feb 24 '14 at 07:39
  • 2
    @JanDudek If you were using `height=device-height` you can switch to `width=device-width` to have the same effect as before without being affected by the status bar change. – Tsunamis Apr 29 '14 at 11:19
36

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

German Attanasio
  • 22,217
  • 7
  • 47
  • 63
  • 4
    This is definitely the easiest answer to implement and works for me. – Ian Jamieson Feb 18 '14 at 09:24
  • Problem with this, as far as cordova implantation, is that when you start the app in landscape it renders the app in portrait. Then after that you have a bar that takes up 1/4 of the screen. have not found a fix for it yet – tik27 Feb 28 '14 at 16:35
  • 1
    Best answer, but how can I add this via the top-level config.xml at build-time? – Red2678 Apr 07 '14 at 16:44
9

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!

Zane
  • 91
  • 1
  • 3
6

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);
        } 
    } 
}
Loïc Faure-Lacroix
  • 13,220
  • 6
  • 67
  • 99
Moeez Akram
  • 469
  • 3
  • 12
5

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.

jnawaz
  • 134
  • 3
5

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.

Irfan
  • 4,301
  • 6
  • 29
  • 46
jotav
  • 76
  • 3
5

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];
}
trueicecold
  • 820
  • 10
  • 23
5

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.

dk123
  • 18,684
  • 20
  • 70
  • 77
4

Better to have this things in info.plist

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

this makes no status bar at all.

kiran
  • 181
  • 1
  • 1
  • 12
3

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.

Franc
  • 424
  • 3
  • 3
3

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.

jomafer
  • 2,655
  • 1
  • 32
  • 47
Liangjun
  • 601
  • 4
  • 13
3
 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);
    }
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Akshay
  • 425
  • 1
  • 5
  • 16
2

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.

Aaron B. Russell
  • 2,416
  • 1
  • 19
  • 22
2

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! :)

Ehsan
  • 1,245
  • 11
  • 20
  • If you are going to copy this solution and paste in your tutorial, please do referencing! THANKS – Ehsan Oct 09 '13 at 10:55
  • This didn't work for me (i.e. it did not hide the status bar). However this answer that involves setting a preference in `MainViewController.m` does seem to work OK: http://stackoverflow.com/a/19571259/539883 – Ade Nov 12 '13 at 22:20
2

In .plist file set property:

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

It hides the statusBar.

Irfan
  • 4,301
  • 6
  • 29
  • 46
asmad
  • 387
  • 4
  • 13
1

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

luster
  • 148
  • 4
1

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.

Irfan
  • 4,301
  • 6
  • 29
  • 46
Chris Fox
  • 641
  • 6
  • 10
1

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];
}
oskarsprima
  • 109
  • 1
  • 2
0

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;
}
Dan Schien
  • 1,392
  • 1
  • 17
  • 29
0

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;
  }
byJeevan
  • 3,728
  • 3
  • 37
  • 60
user3085992
  • 163
  • 1
  • 11
0

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

}
Mytee
  • 21
  • 2
0

For iPhoneX

For all the answers above :

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

Musa almatri
  • 5,596
  • 2
  • 34
  • 33
-1

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';
}
capitannaranja
  • 169
  • 2
  • 7
-2

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.

Irfan
  • 4,301
  • 6
  • 29
  • 46
Joaquin
  • 117
  • 1
  • 4