iOS 7 – 状态栏与视图重叠

我有一个在UINavigationcontroller里面的ViewController ,但是navigationBar是隐藏的。 当我在iOS 7上运行应用程序时,状态栏显示在我的视图之上。 有没有办法避免这种情况?

我不想写任何操作系统特定的代码。

在这里输入图像说明

我试图将View controller-based status bar appearanceNO ,但没有解决问题。

Xcode 5拥有iOS 6/7 Deltas ,专门用于解决此问题。 在故事板中,我将视angular向下移动20个像素,以在iOS 7上正确显示,为了使其与iOS 6兼容,我将Delta y更改为-20。

在这里输入图像描述

由于我的故事板不使用自动布局,为了在iOS 6上正确调整视图的高度,我必须设置Delta height以及Delta Y

如果你根本不需要任何状态栏,则需要用这些数据更新你的plist:为此,在plist中添加这两个设置:

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

在iOS 7中,您需要考虑重叠的透明状态栏来devise您的应用程序。 例如,查看新的iOS 7天气应用程序。

这是iOS 7上UIViewController的默认行为。视图将是全屏,这意味着状态栏将覆盖视图的顶部。

如果在UINavigationController有一个UIViewController并且navigationBar是可见的,那么可以在viewDidLoad包含以下代码,或者为navigationBar提供一个背景图片。

 self.edgesForExtendedLayout = UIRectEdgeNone; 

如果你有隐藏的navigationBar,那么你必须通过移动20点来调整所有的UIView元素。 我没有看到任何其他解决scheme。 使用自动布局将有一点帮助。

如果要向后兼容,以下是用于检测iOS版本的示例代码。

 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; } 

只有我自己做的解决scheme。

这是我的UIViewController子类https://github.com/comonitos/ios7_overlaping

1 UIViewController的子类

2从你的类window.rootViewController子类。

3瞧!

 - (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添加这个使你的状态栏变成白色就在[self.window makeKeyAndVisible]之后。 !

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; } 
 -(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); } } } 

在plist中添加键—查看基于控制器的状态栏外观:NO

要在ios7中隐藏状态栏,请执行以下简单步骤:

在Xcode转到“ Resources ”文件夹,并打开“ (app name)-Info.plist file ”。

  • 检查“ View controller based status bar appearance ”键并将其值设置为“ NO
  • 检查“ Status bar is initially hidden ”键并将其值设置为“ YES

如果密钥不存在,那么可以通过select顶部的“ information property list ”来添加它,然后单击+图标

如果你想完全隐藏它,只是避免处理它,这个效果很好。

 -(BOOL) prefersStatusBarHidden { return YES; } 

参考https://stackoverflow.com/a/18873777/1030449

如果使用xib s,一个非常简单的实现就是使用resize标记(您已经使用3.5“和4”兼容性)来封装容器视图内的所有子视图,以便视图层次结构看起来像这样

xib heirarchy

然后在viewDidLoad ,做这样的事情:

 - (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; } } 

这样,笔尖不需要修改为iOS 7兼容性。 如果你有一个背景,它可以保存在containerView之外,让它覆盖整个屏幕。

这是删除状态栏所需的全部内容。 在这里输入图像描述

对于导航栏:

编写这个代码:

 self.navigationController.navigationBar.translucent = NO; 

只是为我做了诡计。

文森特的答案edgesForExtendedLayout为我工作。

这些macros有助于确定操作系统版本,使其更容易

 // 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) 

将这些macros添加到项目的prefix.pch文件,并可以在任何地方访问

 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 } 

我已经发布了我的答案与另一个职位与这一个相同的问题。

从Apple iOS7转换指南, https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/AppearanceCustomization.html#//apple_ref/doc/uid/TP40013174-CH15-SW1

具体而言, automaticallyAdjustsScrollViewInsets=YES set self.edgesForExtendedLayout = UIRectEdgeNone automaticallyAdjustsScrollViewInsets=YESset self.edgesForExtendedLayout = UIRectEdgeNone适合我,当我不想重叠,我有一个tableviewcontroller

如果你想“使用Autolayout”在任何成本启用viewdidload下面的代码。

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { self.edgesForExtendedLayout = UIRectEdgeNone; self.extendedLayoutIncludesOpaqueBars = NO; self.automaticallyAdjustsScrollViewInsets = NO; } 

从YTPlayer的横向视图返回后,状态栏和导航栏重叠。 这是我的解决scheme后,尝试@comonitos的版本,但不适用于我的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; } } } 

只要你想修改导航栏的位置就调用这个函数。 我调用了YTPlayerViewDelegate的playerView:didChangeToState:

 - (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state { switch (state) { case kYTPlayerStatePaused: case kYTPlayerStateEnded: [self fixNavigationBarPosition]; break; default: } }