在iOS 7中,UIStatusBar被设计成这样,它与视图合并:

(GUI由Tina tavvar设计)

It is cool, but it will somewhat mess up your view when you have something at the top part of your view, and it becomes overlapped with the status bar. Is there a simple solution (such as setting a property in info.plist) that can change the way it works [not overlapping] back to how it is in iOS6? I know a more straightforward solution is to have self.view.center.x + 20 points for every single view controller, but changing them will screw other dimensions up (having a different self.view.center.x can cause problem to custom segues, etc.) and suddenly it turns into a tedious job that is best to be avoided. I'll really be glad if someone can provide me an one-liner solution for this.

附注:我知道我可以隐藏状态栏

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];

在didFinishLaunchingWithOptions方法中,但这是一个变通方法,一个避免问题的快捷方式,所以我不认为这是一个真正的解决方案。


当前回答

如果你正在使用接口构建器,试试这个:

在你的xib文件中:

1)选择主视图,设置背景颜色为黑色(或任何你想要状态栏的颜色)

2) Make sure the background is a self contained subview positioned as a top level child of the controller's view. Move your background to become a direct child of the controller's view. Check the autosizing panel to be sure that you've locked all frame edges, activated both flexibility axes, and if this is a UIImageView, set the content mode to Scale to fill. Programmatically this translates to contentMode set to UIViewContentModeScaleToFill and has its auto resizing mask set to (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight).

3)现在将所有被锁定的东西上下移动20点,并设置iOS 6/7 delta Y为-20。 在自动缩放面板中,所有被锁定在顶部框架上的顶级子图层都需要向下移动20点,并将其iOS 6/7 delta Y设置为-20。(Cmd选择所有这些,并按下箭头20次-有更好的方法吗?)

4) Adjust the iOS 6/7 delta height of all of the above items that had a flexible height. Any of the items that were locked to the frame top and bottom and had flexible height enabled in the autosizing panel must also have their iOS 6/7 delta height set to 20. That includes the background view mentioned above. This may seem anti-intuitive, but due to the order in which these are applied, it is necessary. The frame height is set first (based on device), then the deltas are applied, and finally the autosizing masks are applied based upon the offset positions of all of the child frames - think it through for a bit, it will make sense.

5)最后,被锁定在底部框架而不是顶部框架的项目根本不需要delta。

这将给你在iOS7和iOS6中相同的状态栏。

另一方面,如果你想要iOS7样式同时保持iOS6兼容性,那么将背景视图的delta Y / delta height值设置为0。

要查看更多iOS7迁移信息,请阅读全文:http://uncompiled.blogspot.com/2013/09/legacy-compatible-offsets-in-ios7.html

其他回答

如果你不希望你的视图控制器被状态栏(和导航栏)重叠,在Xcode 5的Interface Builder中取消选中“在顶部栏下扩展边缘”框。

Interface Builder中有一个选项,调用iOS 6/7 Delta属性,旨在解决偏移问题。

在Stack Overflow的问题界面构建器:什么是UIView的布局iOS 6/7 delta ?

更新(新解决方案) 本次更新是iOS 7导航栏问题的最佳解决方案。您可以设置导航栏颜色示例:FakeNavBar。backgroundColor = [UIColor redColor]; 注意:如果你使用默认的导航控制器,请使用旧的解决方案。 AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    if(NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_7_0)
    {
        UIView *FakeNavBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 20)];
        FakeNavBar.backgroundColor = [UIColor whiteColor];

        float navBarHeight = 20.0;
        for (UIView *subView in self.window.subviews) {

            if ([subView isKindOfClass:[UIScrollView class]]) {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height - navBarHeight);
            } else {
                subView.frame = CGRectMake(subView.frame.origin.x, subView.frame.origin.y + navBarHeight, subView.frame.size.width, subView.frame.size.height);
            }
        }
        [self.window addSubview:FakeNavBar];
    }

    return YES;

}

旧的解决方案-如果你使用以前的代码,请忽略下面的代码和图像 这是旧版本的iOS 7导航栏解决方案。

我用以下代码解决了这个问题。这是用来添加状态栏的。 didFinishLaunchingWithOptions

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    UIView *addStatusBar = [[UIView alloc] init];
    addStatusBar.frame = CGRectMake(0, 0, 320, 20);
    addStatusBar.backgroundColor = [UIColor colorWithRed:0.973 green:0.973 blue:0.973 alpha:1]; //change this to match your navigation bar
    [self.window.rootViewController.view addSubview:addStatusBar];
}

对于界面构建器,这是在iOS 6中打开的;它从0像素开始。

注意:iOS 6/7只有在详细信息窗格的“文件检查器”(最左边的图标)中取消视图控制器的“使用自动布局”时才会出现增量。

我非常简单的解决方案(假设你只支持垂直方向)是重新定义iOS版本7以下的应用程序窗口边界,在App委托didFinishLaunchingWithOptions方法中:

CGRect screenBounds = [[UIScreen mainScreen] bounds];
if ([HMService getIOSVersion] < 7) {
    // handling statusBar (iOS6) by leaving top 20px for statusbar.
    screenBounds.origin.y = 20;
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}
else {
    self.window = [[UIWindow alloc] initWithFrame:screenBounds];
}

因为使用presentViewController:animated:completion:把window.rootViewController弄乱了。因此,我必须找到一个不同的方法来解决这个问题。我终于让它与模态和旋转工作通过子类化我的rootViewController的UIView。

.h

@interface RootView : UIView

@end

.m

@implementation RootView

-(void)setFrame:(CGRect)frame
{
    if (self.superview && self.superview != self.window)
    {
        frame = self.superview.bounds;
        frame.origin.y += 20.f;
        frame.size.height -= 20.f;
    }
    else
    {
        frame = [UIScreen mainScreen].applicationFrame;
    }

    [super setFrame:frame];
}

- (void)layoutSubviews
{
    self.frame = self.frame;

    [super layoutSubviews];
}

@end

现在你有了iOS7动画的强大解决方案。