Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

iPad status bar covers up my app's top UIViews; okay after rotation

I wrote an iPad app. When it is first started up (in iPhone simulator, or on real iPad) all the UIViews at the top of my window are partially covered-up by the iPads time/battery status bar.

After I rotate the iPad (simulator or real one) the problem goes away: my UIViews appear shifted down, so they are under (below) the status bar. In other words, after I do the first rotation, the iPad knows to push my window downwards about 20 pixels to make room for the status bar. But before the first rotation (simulator or hardware) the iPad is not shifting my UIViews downward.

Question: What can I do in software (during the startup logic) to get the iPad to push my window down to make room for the status bar?

I think the iPad should do it automatically for me, but since it is not, I'm willing to take some action in the software to get it to happen. Any thoughts? NOTE: When I create all my UIViews, I'm using a coordinate of (0,0) for my upper left corner, which is correct, and after the first rotation everything works great. Also: I have auto-rotation enabled, so my app is always rotating to keep its display "up" so users can view it in all 4 rotations.

iPad, iPhone OS 3.1.3

Posted on Nov 23, 2010 9:40 AM

Reply
30 replies

Nov 29, 2010 7:00 PM in response to xnav

My frame is (0,0,768,1024). That is, the full resolution. I do not draw anything in the "far" 20 or so pixels, since that may be pushed-off the screen by the Status Bar.

The above frame works great after the iPad is rotated once. But when the app first comes up: the Status Bar is obscuring the top 20 pixels of my app's GUI.

I totally ignore the Status Bar in my app. I pretend it does not exist, and reference all my views to an upper-left coordinate of (0,0).

Nov 29, 2010 11:37 PM in response to David Restler

Hi David -
David Restler wrote:
Question: What can I do in software (during the startup logic) to get the iPad to push my window down to make room for the status bar?

If you're creating the view in your code, you're explicitly setting the view frame. The controller then assumes you know what you're doing and doesn't make any adjustment for the status bar (or any other bars that may be above or below the content area).

In other words, when you explicitly set the frame in loadView, you're buying sole responsibility for the starting dimensions. In the case of an iPad with only the status bar, you need to drop the y-origin down 20, and shorten the height by 20:

- (void)loadView {
CGRect frame = CGRectMake(0, 20, 768, 1004);
UIView *v = [[UIView alloc] initWithFrame:frame];
self.view = v;
[v release];
NSLog(@"%s: self.view=%@ self.view.frame=%@",
_func_, self.view, NSStringFromCGRect(self.view.frame));
}

Btw, if you ever open your IB, try adding and subtracting the various simulated bars while watching the dimensions of the view in the Size Inspector. If the view is the main content view (i.e. connected to the 'view' outlet of File's Owner), you should see the y-origin and size adjust for each combination of bars. In fact, those dimensions will probably be grayed out, since IB doesn't trust us with such critical numbers. The point is, that when a view is loaded from a nib built with the correct simulated bars, the adjustment for the bars has already been saved in that file.
I think the iPad should do it automatically for me

If you want to see what the controller does by default (i.e. no nib and no frame defined in loadView), try this code:

// MyAppDelegate.m
#import "MyAppDelegate.h"
#import "MyViewController.h"
@implementation MyAppDelegate
@synthesize window, viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
MyViewController *vc = [[MyViewController alloc] initWithNibName:nil bundle:nil];
vc.view.backgroundColor = [UIColor grayColor];
self.viewController = vc;
[vc release];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
NSLog(@"%s: viewController.view.frame=%@",
_func_, NSStringFromCGRect(viewController.view.frame));
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
// MyViewController.m
#import "MyViewController.h"
@implementation MyViewController
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
@end

When no nib name is specified, and the view loader can't find a nib that matches the owner's class name, and loadView isn't overridden, the view controller creates a default view (see no. 3 under "The steps that occur during the load cycle are as follows:" in [Understanding the View Management Cycle|http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGf oriPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP 40007457-CH101-SW19] in the View Controller Programming Guide for iOS). If you run the above example code, you should see the frame of the default view takes all bars into account.
... I'm using a coordinate of (0,0) for my upper left corner, which is correct

As explained above, it's not correct if there are any upper bars
and after the first rotation everything works great.

Yes, all bets are off after an auto-rotation. The system recalculates the content view frame in that case (though that math doesn't always come out the way you want).

Hope that helps to unscramble things a little!
- Ray

Dec 2, 2010 3:31 AM in response to xnav

Hey X -
xnav wrote:
Create a new iPad View based project called 'frame'.
Double click on frameViewController.xib to start IB.
Select View and examine its dimensions with the Size Inspector.

Yup, I see. But next log the frame in viewDidLoad. I think you'll see (0,20,768,1004). Else if the frame is (0,0,768,1004) in viewDidLoad, I think you'll see a 20 pixel gap between the bottom of the view and the bottom of the window. I've seen both outcomes at runtime when the Size Inspector has shown the view origin to be (0,0). I.e., when the status bar is showing, the controller either knows or doesn't know to push the view down 20, and I"ve never been able to find out when it knows and when it doesn't 😟

For example in an iPhone project, when starting with a clean View-based template, the Size Inspector shows the view origin at (0,0), but by the time viewDidLoad runs, the origin has been consistently pushed down 20. But this won't always be the case when I construct my own xib. Sometimes IB locks the origin at (0,0) and it isn't pushed down at runtime, in which case I"ve had to make the correction manually in viewDidLoad.

The reason I recommended (0,20,768,1004), i.e. lowering the y-origin 20 pixels, is that I don't think the controller will correct the origin when it's been explicitly set in loadView. It seems like the controller respects a loadView setting, but may or may not trust a (0,0) origin in an xib.

I don't mean to pass off this hypothesis as knowledge, but so far it's the only one that seems to fit my experience. I think I love black boxes as much as the next OO fan boy.. but now and then it might be nice to know what the freaking controller is actually doing.

\- Ray

May 2, 2011 9:08 AM in response to David Restler

Hi David,

I may be new to all this but I'm busy writing iPhone/Pod/Pad Universal apps and have some experience in iPhone/iPod app development.


Can't you just switch the status bar off or use the application frame - thereby dodging the status bar completely?


1) [[UIApplicationsharedApplication] setStatusBarHidden: TRUE];

2) [selfsetWindow: [[UIWindowalloc] initWithFrame: [[UIScreenmainScreen] applicationFrame]]];

I use (1) followed by (2) in all of my iApps now and I've never had a problem.

Hope this helps.

Jul 19, 2011 6:29 AM in response to MrChadBag

Actually it isn't. I did look. I am using Xcode 4.0.2. The attributes inspector for both the view and the view controller does not have it.


I solved the problem this way. Fixes it if and when it is wrong.


- (void) viewWillAppear:(BOOL)animated

{

CGRect arect=[[UIScreenmainScreen]applicationFrame];

CGRect anotherrect=[[UIApplicationsharedApplication]statusBarFrame];

if(self.view.center.y==arect.size.height/2)

self.view.center=CGPointMake(self.view.center.x, self.view.center.y+anotherrect.size.height); // fix silliness in IB that makes view start 20 pixels higher than it should on iPhone

iPad status bar covers up my app's top UIViews; okay after rotation

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.