I built my app to have a translucent navbar in iOS 6. I'd like to utilize the translucent status bar in iOS 7 and keep the app as is in iOS 6, but my content is always underneath the status bar in iOS 7, with 20px missing on the bottom. I figure that I can make the very tedious code changes that check whether the device has iOS 7 and then adjust my content accordingly, but I fear that this is going to be a lot of work.
Ideally, I'd like to add 20px of padding to the top of every view controller's view, so that the content shifts down, and still functions fine with an opaque navbar on iOS 6.
I've read the threads that exist on the subject 1 2, but none of the answers provided solved my problem.
I should note that I am NOT using Interface Builder and all my VCs are being created programmatically.
If you are using auto layout
, then all you need to do is add a Vertical Constraint
from your top most view to Top Layout Guide
as shown below and it should take care the top spacing.
For more info:
https://developer.apple.com/library/ios/qa/qa1797/_index.html
You can use the new Xcode 5 feature of iOS6/7 deltas to set -20 to all your view, which will give you a similar experience. Set your views correctly for iOS7 in interface builder, and use deltas for iOS6 support.
Here's what I did to always pad the top of my view with 20px (height of the status bar).
I used this code in my AppDelegate's application:didFinishLaunchingWithOptions: method
...
// container holds my root view controller
UINavigationController *container = [UINavigationController alloc] init...];
...
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { // iOS 7
// Create parent controller that will contain your existing root view controller's view shifted 20 px down to account for the status bar.
UIViewController *newRootController = [[UIViewController alloc] init];
// Add my old root view controller as a child
[newRootController addChildViewController:container];
// Add its view as a subview
[newRootController.view addSubview:container.view];
// Call this method because it does some configuration?
[container didMoveToParentViewController:newRootController];
// Now just position the view starting at point (0, 20)
UIView *aView = container.view;
NSDictionary *viewDictionary = NSDictionaryOfVariableBindings(aView);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[aView]|" options:0 metrics:nil views:viewDictionary];
[newRootController.view addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[aView]|" options:0 metrics:nil views:viewDictionary];
[newRootController.view addConstraints:constraints];
self.window.rootViewController = newRootController;
} else { // pre iOS 7
self.window.rootViewController = container;
}
Now whenever you're in iOS 7, everything will exist in the root view controller's view that is shifted 20 pixels down. You'll only have to do this once in your AppDelegate.
Set UIViewControllerBasedStatusBarAppearance' to NO in info.plist (To opt out of having view controllers adjust the status bar style so that we can set the status bar style by using the
UIApplicationstatusBarStyle` method.)
In AppDelegate's application:didFinishLaunchingWithOptions, call
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);
//Added on 19th Sep 2013
self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
}
return YES;
You can disable the view going under the top bar in ios 7 by setting the following:
if([controller canPerformAction:@selector(setEdgesForExtendedLayout:) withSender:self]) {
[controller setEdgesForExtendedLayout:UIRectEdgeBottom | UIRectEdgeLeft | UIRectEdgeRight];
}