I have a ViewController
which is inside a UINavigationcontroller
, but the navigationBar is hidden. When I run the app on iOS 7, the status bar shows on top of my view. Is there a way to avoid this?
I don't want to write any OS specific code.
I tried setting View controller-based status bar appearance
to NO
, but it did not fix the issue.
If you want "Use Autolayout" to be enabled at any cost place the following code in viewdidload.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = NO;
self.automaticallyAdjustsScrollViewInsets = NO;
}
Vincent's answer edgesForExtendedLayout worked for me.
These macros help in determining os version making it easier
// 7.0 and above
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending)
add these macros to prefix.pch file of your project and can be accessed anywhere
if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
//some iOS 7 stuff
self.edgesForExtendedLayout = UIRectEdgeNone;
}
if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
// some old iOS stuff
}
To hide status bar in ios7 follow these simple steps :
In Xcode goto "Resources
" folder and open "(app name)-Info.plist file
".
View controller based status bar appearance
" key and set its value "NO
" Status bar is initially hidden
" key and set its value "YES
"If the keys are not there then you can add it by selecting "information property list
" at top and click + icon
This is the default behaviour for UIViewController
on iOS 7. The view will be full-screen which means the status bar will cover the top of your view.
If you have a UIViewController
within a UINavigationController
and the navigationBar is visible, you can have the following code in your viewDidLoad
or have a background image for navigationBar do the trick.
self.edgesForExtendedLayout = UIRectEdgeNone;
If you have navigationBar hidden, then you have to adjust all the UIView elements by shifting 20 points. I dont't see any other solution. Use auto layout will help a little bit.
Here is the sample code for detecting the iOS version, if you want to backward compatibility.
NSUInteger DeviceSystemMajorVersion() {
static NSUInteger _deviceSystemMajorVersion = -1;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSString *systemVersion = [UIDevice currentDevice].systemVersion;
_deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
});
return _deviceSystemMajorVersion;
}
-(UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
-(void)viewWillLayoutSubviews{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.view.clipsToBounds = YES;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenHeight = 0.0;
if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
screenHeight = screenRect.size.height;
else
screenHeight = screenRect.size.width;
CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
if (!CGRectEqualToRect(screenFrame, viewFrame1))
{
self.view.frame = screenFrame;
self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
}
}
Add Key in plist--- View controller-based status bar appearance : NO
This is all that is needed to remove the status bar.
If you simply do NOT want any status bar at all, you need to update your plist with this data: To do this, in the plist, add those 2 settings:
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
In iOS 7 you are expected to design your app with an overlaid transparent status bar in mind. See the new iOS 7 Weather app for example.
Only working solution i've made by my self.
Here is my UIViewController subclass https://github.com/comonitos/ios7_overlaping
1 Subclass from UIViewController
2 Subclass your window.rootViewController from that class.
3 Voila!
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect screen = [[UIScreen mainScreen] bounds];
if (self.navigationController) {
CGRect frame = self.navigationController.view.frame;
frame.origin.y = 20;
frame.size.height = screen.size.height - 20;
self.navigationController.view.frame = frame;
} else {
if ([self respondsToSelector: @selector(containerView)]) {
UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];
CGRect frame = containerView.frame;
frame.origin.y = 20;
frame.size.height = screen.size.height - 20;
containerView.frame = frame;
} else {
CGRect frame = self.view.frame;
frame.origin.y = 20;
frame.size.height = screen.size.height - 20;
self.view.frame = frame;
}
}
}
}
4 Add this to make your status bar white Just right after the [self.window makeKeyAndVisible]; !!!
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
If you wan to hide it completely and just avoid dealing with it, this works well.
-(BOOL) prefersStatusBarHidden
{
return YES;
}
My status bar and navigation bar overlap after return from landscape view of YTPlayer. Here is my solution after trying @comonitos' version but not work on my iOS 8
- (void)fixNavigationBarPosition {
if (self.navigationController) {
CGRect frame = self.navigationController.navigationBar.frame;
if (frame.origin.y != 20.f) {
frame.origin.y = 20.f;
self.navigationController.navigationBar.frame = frame;
}
}
}
Just call this function whenever you want to fix the position of navigation bar. I called on YTPlayerViewDelegate's playerView:didChangeToState:
- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
switch (state) {
case kYTPlayerStatePaused:
case kYTPlayerStateEnded:
[self fixNavigationBarPosition];
break;
default:
}
}
If using xib
s, a very easy implementation is to encapsulate all subviews inside a container view with resizing flags (which you'll already be using for 3.5" and 4" compatibility) so that the view hierarchy looks something like this
and then in viewDidLoad
, do something like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// initializations
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
{
CGRect frame = containerView.frame;
frame.origin.y += 20;
frame.size.height -= 20;
containerView.frame = frame;
}
}
This way, the nibs need not be modified for iOS 7 compatibility. If you have a background, it can be kept outside containerView
and let it cover the whole screen.
I have posted my answer to another post with the same question with this one.
From Apple iOS7 transition Guide, https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1
Specifically automaticallyAdjustsScrollViewInsets=YES
and set self.edgesForExtendedLayout = UIRectEdgeNone
works for me when I don't want to the overlap and I have a tableviewcontroller
.
For Navigation Bar :
Writing this code :
self.navigationController.navigationBar.translucent = NO;
just did the trick for me.
Source: Stackoverflow.com