简体   繁体   English

iOS 7 - 状态栏与视图重叠

[英]iOS 7 - Status bar overlaps the view

I have a ViewController which is inside a UINavigationcontroller , but the navigationBar is hidden. 我有一个ViewController ,它在UINavigationcontroller ,但是navigationBar是隐藏的。 When I run the app on iOS 7, the status bar shows on top of my view. 当我在iOS 7上运行应用程序时,状态栏显示在我的视图之上。 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. 我尝试将View controller-based status bar appearanceNO ,但它没有解决问题。

Xcode 5 has iOS 6/7 Deltas which is specifically made to resolve this issue. Xcode 5具有iOS 6/7 Deltas ,专门用于解决此问题。 In the storyboard, I moved my views 20 pixels down to look right on iOS 7 and in order to make it iOS 6 compatible, I changed Delta y to -20. 在故事板中,我将视图向下移动了20个像素,在iOS 7上向右看,为了使iOS 6兼容,我将Delta y更改为-20。

在此输入图像描述

Since my storyboard is not using auto-layout, in order to resize the height of views properly on iOS 6 I had to set Delta height as well as Delta Y . 由于我的故事板没有使用自动布局,为了在iOS 6上正确调整视图的高度,我必须设置Delta height以及Delta Y

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

<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. 在iOS 7中,您需要设计一个覆盖透明状态栏的应用程序。 See the new iOS 7 Weather app for example. 例如,请参阅新的iOS 7天气应用程序。

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. 这是iOS 7上UIViewController的默认行为。视图将是全屏的,这意味着状态栏将覆盖视图的顶部。

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. 如果UINavigationControllerUIViewController并且navigationBar可见,则可以在viewDidLoad使用以下代码,或者使用navigationBar的背景图像。

self.edgesForExtendedLayout = UIRectEdgeNone;

If you have navigationBar hidden, then you have to adjust all the UIView elements by shifting 20 points. 如果您隐藏了navigationBar,则必须通过移动20个点来调整所有UIView元素。 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. 以下是用于检测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;
}

Only working solution i've made by my self. 只有我自己做的工作解决方案。

Here is my UIViewController subclass https://github.com/comonitos/ios7_overlaping 这是我的UIViewController子类https://github.com/comonitos/ios7_overlaping

1 Subclass from UIViewController 来自UIViewController的1个子类

2 Subclass your window.rootViewController from that class. 2从该类中对window.rootViewController进行子类化。

3 Voila! 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 Add this to make your status bar white Just right after the [self.window makeKeyAndVisible]; 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);
    }
  }
}

Add Key in plist--- View controller-based status bar appearance : NO 在plist中添加键---查看基于控制器的状态栏外观:NO

To hide status bar in ios7 follow these simple steps : 要在ios7中隐藏状态栏,请按照以下简单步骤操作:

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

  • check for " View controller based status bar appearance " key and set its value " NO " 检查“ View controller based status bar appearance ”键并将其值设置为“ NO
  • check for " Status bar is initially hidden " key and set its value " YES " 检查“ Status bar is initially hidden ”键并将其值设置为“ YES

If the keys are not there then you can add it by selecting " information property list " at top and click + icon 如果没有按键,则可以通过选择顶部的“ information property list ”添加它,然后单击+图标

If you wan to hide it completely and just avoid dealing with it, this works well. 如果你想完全隐藏它并且避免处理它,这很好用。

-(BOOL) prefersStatusBarHidden
{
    return YES;
}

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

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 如果使用xib ,一个非常简单的实现是将所有子视图封装在容器视图中,并使用调整大小标记(您已经将其用于3.5“和4”兼容性),以便视图层次结构看起来像这样

xib heirarchy

and then in viewDidLoad , do something like this: 然后在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;
  }
}

This way, the nibs need not be modified for iOS 7 compatibility. 这样,无需修改nib即可兼容iOS 7。 If you have a background, it can be kept outside containerView and let it cover the whole screen. 如果你有背景,它可以保存在containerView外面,让它覆盖整个屏幕。

This is all that is needed to remove the status bar. 这是删除状态栏所需的全部内容。 在此输入图像描述

For Navigation Bar : 对于导航栏:

Writing this code : 编写这段代码:

self.navigationController.navigationBar.translucent = NO;

just did the trick for me. 只是为我做了伎俩。

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 从Apple iOS7过渡指南, 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 . 特别是automaticallyAdjustsScrollViewInsets=YESset self.edgesForExtendedLayout = UIRectEdgeNone对我来说当我不想重叠时我有一个tableviewcontroller

Vincent's answer edgesForExtendedLayout worked for me. Vincent的回答edgesForExtendedLayout为我工作。

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

If you want "Use Autolayout" to be enabled at any cost place the following code in viewdidload. 如果您想以任何代价启用“使用Autolayout”,请在viewdidload中添加以下代码。

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

My status bar and navigation bar overlap after return from landscape view of YTPlayer. 从YTPlayer的横向视图返回后,我的状态栏和导航栏重叠。 Here is my solution after trying @comonitos' version but not work on my iOS 8 这是我尝试@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;
        }
    }
}

Just call this function whenever you want to fix the position of navigation bar. 只要想要修复导航栏的位置,就可以调用此函数。 I called on YTPlayerViewDelegate's playerView:didChangeToState: 我打电话给YTPlayerViewDelegate的playerView:didChangeToState:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM