In iOS 7 the UIStatusBar
has been designed in a way that it merges with the view like this:
Updates on 19th Sep 2013:
fixed scaling bugs by adding
self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
corrected typos in the
NSNotificationCenter
statement
Updates on 12th Sep 2013:
corrected
UIViewControllerBasedStatusBarAppearance
toNO
added a solution for apps with screen rotation
added an approach to change the background color of the status bar.
There is, apparently, no way to revert the iOS7 status bar back to how it works in iOS6.
However, we can always write some codes and turn the status bar into iOS6-like, and this is the shortest way I can come up with:
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 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
[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;
in order to:
Check if it's iOS 7.
Set status bar's content to be white, as opposed to UIStatusBarStyleDefault.
Avoid subviews whose frames extend beyond the visible bounds from showing up (for views animating into the main view from top).
Create the illusion that the status bar takes up space like how it is in iOS 6 by shifting and resizing the app's window frame.
use NSNotificationCenter to detect orientation changes by adding
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidChangeStatusBarOrientation:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
in if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
and create a new method in AppDelegate:
- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
int a = [[notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey] intValue];
int w = [[UIScreen mainScreen] bounds].size.width;
int h = [[UIScreen mainScreen] bounds].size.height;
switch(a){
case 4:
self.window.frame = CGRectMake(0,20,w,h);
break;
case 3:
self.window.frame = CGRectMake(-20,0,w-20,h+20);
break;
case 2:
self.window.frame = CGRectMake(0,-20,w,h);
break;
case 1:
self.window.frame = CGRectMake(20,0,w-20,h+20);
}
}
So that when orientation changes, it will trigger a switch statement to detect app's screen orientation (Portrait, Upside Down, Landscape Left, or Landscape Right) and change the app's window frame respectively to create the iOS 6 status bar illusion.
Add
@property (retain, nonatomic) UIWindow *background;
in AppDelegate.h
to make background
a property in your class and prevent ARC from deallocating it. (You don't have to do it if you are not using ARC.)
After that you just need to create the UIWindow in if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
:
background = [[UIWindow alloc] initWithFrame: CGRectMake(0, 0, self.window.frame.size.width, 20)];
background.backgroundColor =[UIColor redColor];
[background setHidden:NO];
Don't forget to @synthesize background;
after @implementation AppDelegate
!
The easiest way to do so is installing an older SDK to your newest Xcode.
How to install older SDK to the newest Xcode?
U can get the iOS 6.1 SDK from http://www.4shared.com/zip/NlPgsxz6/iPhoneOS61sdk.html or downloading an older Xcode and geting the SDK from its contents
Unzip and paste this folder to /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs
Restart the xcode.
Hope it helps you. It worked for me =)
UPDATE(NEW SOLUTION)
This update is the best solution of iOS 7 navigation bar problem.You can set navigation bar color example: FakeNavBar.backgroundColor = [UIColor redColor];
Note : If you use default Navigation Controller please use old solution.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
{
UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
FakeNavBar.backgroundColor = [UIColor whiteColor];
float navBarHeight = 20.0;
for (UIView *subView in self.window.subviews) {
if ([subView isKindOfClass:[UIScrollView class]]) {
subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
} else {
subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
}
}
[self.window addSubview:FakeNavBar];
}
return YES;
}
OLD SOLUTION - IF you use previous code please ignore following Code and Image
This is old version of iOS 7 navigation bar solution.
I solved the problem with the following code. This is for adding a status bar.
didFinishLaunchingWithOptions
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 320, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
[self.window.rootViewController.view addSubview:addStatusBar];
}
And for Interface Builder this is for when you open with iOS 6; it is starting at 0 pixels.
I am late for this Answer, but i just want to share what i did, which is basically the easiest solution
First of all-> Go to your info.plist
File and add Status Bar Style->Transparent Black Style(Alpha of 0.5)
Now ,here it Goes:-
Add this code in your AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Whatever your code goes here
if(kDeviceiPad){
//adding status bar for IOS7 ipad
if (IS_IOS7) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 1024, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //change this to match your navigation bar
[self.window.rootViewController.view addSubview:addStatusBar];
}
}
else{
//adding status bar for IOS7 iphone
if (IS_IOS7) {
UIView *addStatusBar = [[UIView alloc] init];
addStatusBar.frame = CGRectMake(0, 0, 320, 20);
addStatusBar.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1]; //You can give your own color pattern
[self.window.rootViewController.view addSubview:addStatusBar];
}
return YES;
}
I have viewed many many many many and many tutorials to fix this darn problem. But none of them works! Here is my solution, and it works for me:
if( [[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f ) {
float statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;
for( UIView *v in [self.view subviews] ) {
CGRect rect = v.frame;
rect.origin.y += statusBarHeight;
v.frame = rect;
}
}
The logic is simple. I shift all children views on the self.view with 20 pixels. That's all. Then, the screenshot will display just like as iOS 6 did. I hate the iOS7 status bar! ~"~
My solution was to add a UIView
with height of 20 points on top of the window when on iOS 7.
Then I created a method in my AppDelegate class to show/hide the "solid" status bar background. In application:didFinishLaunchingWithOptions:
:
// ...
// Add a status bar background
self.statusBarBackground = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.window.bounds.size.width, 20.0f)];
self.statusBarBackground.backgroundColor = [UIColor blackColor];
self.statusBarBackground.alpha = 0.0;
self.statusBarBackground.userInteractionEnabled = NO;
self.statusBarBackground.layer.zPosition = 999; // Position its layer over all other views
[self.window addSubview:self.statusBarBackground];
// ...
return YES;
Then I created a method to fade in/out the black status bar background:
- (void) showSolidStatusBar:(BOOL) solidStatusBar
{
[UIView animateWithDuration:0.3f animations:^{
if(solidStatusBar)
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
self.statusBarBackground.alpha = 1.0f;
}
else
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
self.statusBarBackground.alpha = 0.0f;
}
}];
}
All I have to do now is call is [appDelegate showSolidStatusBar:YES]
when needed.