iOS 7 – 状态栏与视图重叠
我有一个在UINavigationcontroller
里面的ViewController
,但是navigationBar是隐藏的。 当我在iOS 7上运行应用程序时,状态栏显示在我的视图之上。 有没有办法避免这种情况?
我不想写任何操作系统特定的代码。
我试图将View controller-based status bar appearance
为NO
,但没有解决问题。
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; }
如果使用xib
s,一个非常简单的实现就是使用resize标记(您已经使用3.5“和4”兼容性)来封装容器视图内的所有子视图,以便视图层次结构看起来像这样
然后在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 }
我已经发布了我的答案与另一个职位与这一个相同的问题。
具体而言, automaticallyAdjustsScrollViewInsets=YES
set self.edgesForExtendedLayout = UIRectEdgeNone
automaticallyAdjustsScrollViewInsets=YES
并set 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: } }