iOS 7 - 状态栏与视图重叠

时间:2013-09-12 23:29:05

标签: ios statusbar ios7

我的ViewController位于UINavigationcontroller内,但导航栏已隐藏。当我在iOS 7上运行应用程序时,状态栏显示在我的视图之上。有没有办法避免这种情况?

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

Enter image description here

我尝试将View controller-based status bar appearance设置为NO,但它没有解决问题。

14 个答案:

答案 0 :(得分:95)

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

enter image description here

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

答案 1 :(得分:69)

如果您根本不想要任何状态栏,则需要使用以下数据更新plist: 要执行此操作,请在plist中添加以下两个设置:

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

在iOS 7中,您需要设计一个覆盖透明状态栏的应用程序。例如,请参阅新的iOS 7天气应用程序。

答案 2 :(得分:43)

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

如果UIViewController中有UINavigationController并且导航栏可见,您可以在viewDidLoad中使用以下代码,或者使用navigationBar的背景图片。< / p>

self.edgesForExtendedLayout = UIRectEdgeNone;

如果隐藏了navigationBar,则必须通过移动20个点来调整所有UIView元素。我没有看到任何其他解决方案。使用自动布局会有所帮助。

以下是用于检测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;
}

答案 3 :(得分:15)

只有我自己制作的解决方案。

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

UIViewController的1个子类

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

答案 4 :(得分:13)

-(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中添加键---查看基于控制器的状态栏外观:否

答案 5 :(得分:4)

要在ios7中隐藏状态栏,请按照以下简单步骤操作:

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

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

如果没有按键,则可以在顶部选择“information property list”进行添加,然后点击 + 图标

答案 6 :(得分:3)

如果你想完全隐藏它并且避免处理它,这很有效。

-(BOOL) prefersStatusBarHidden
{
    return YES;
}

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

答案 7 :(得分:3)

如果使用xib,一个非常简单的实现是将所有子视图封装在容器视图中,并调整标志(你已经用于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;
  }
}

这样,不需要修改nib以兼容iOS 7。如果你有背景,可以将其保留在containerView之外,让它覆盖整个屏幕。

答案 8 :(得分:3)

这是删除状态栏所需的全部内容。 enter image description here

答案 9 :(得分:2)

导航栏:

编写此代码:

self.navigationController.navigationBar.translucent = NO;

刚刚为我做了诀窍。

答案 10 :(得分:1)

我已将我的答案发布到另一篇文章中,并附有与此问题相同的问题。

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

具体来说,automaticallyAdjustsScrollViewInsets=YESset self.edgesForExtendedLayout = UIRectEdgeNone适用于我,当我不想重叠时,我有一个tableviewcontroller

答案 11 :(得分:1)

Vincent的回答edgesForExtendedLayout为我工作。

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

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

将这些宏添加到项目的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
}

答案 12 :(得分:0)

如果您想以任何代价启用“使用Autolayout”,请在viewdidload中添加以下代码。

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

答案 13 :(得分:0)

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

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