我最近下载了Xcode 5 DP,在iOS 7上测试我的应用。我注意到并确认的第一件事是,视图的边界并不总是根据状态栏和导航栏调整大小。

在viewDidLayoutSubviews中,我打印了视图的边界:

{{0, 0}, {320, 568}}

这导致我的内容出现在导航栏和状态栏的下方。

我知道我可以通过获取主屏幕的高度,减去状态栏的高度和导航栏的高度来解释高度,但这似乎是不必要的额外工作。

我该如何解决这个问题?

更新:

我已经找到了解决这个问题的方法。将导航栏的半透明属性设置为NO:

self.navigationController.navigationBar.translucent = NO;

这将修复视图被框在导航栏和状态栏下面的问题。

然而,我还没有找到一个修复的情况下,当你想导航栏是半透明的。例如,在全屏查看一张照片时,我希望导航栏是半透明的,视图被框在它下面。这是可行的,但是当我切换显示/隐藏导航栏时,我经历了更奇怪的结果。第一个子视图(一个UIScrollView)每次都会改变它的边界y原点。


当前回答

你不需要计算要往下平移多远,这有一个内置属性。在Interface Builder中,突出显示视图控制器,然后导航到属性检查器。在这里你会看到一些复选框旁边的文字“扩展边缘”。正如你所看到的,在第一个截图中,默认的选择是让内容出现在顶部和底部的栏下,而不是在不透明的栏下,这就是为什么将栏样式设置为不半透明的原因。

正如你在第一张截图中看到的,有两个UI元素隐藏在导航栏下面。这些元素,一个UIButton和一个UISegmentedControl都有他们的“y”原点设为零,视图控制器被设置为允许内容低于顶部栏。

这第二张截图显示了当你取消选择“顶部栏下”复选框时会发生什么。正如你所看到的,视图控制器视图已经适当地向下移动,因为它的y原点在导航栏的正下方。

这也可以通过使用-[UIViewController edgesForExtendedLayout]来实现。这里有一个edgeForExtendedLayout和UIRectEdge类引用的链接

[self setEdgesForExtendedLayout:UIRectEdgeNone];

其他回答

最简单的技巧是打开NIB文件并执行以下两个简单步骤:

只需切换它并将其设置为您喜欢的一个:

选择那些UIView的/UIIMageView的/…你想要下移。在我的例子中,只有徽标重叠,我已经将delta设置为+15;(如果第一步选择iOS 7,则为-15)

结果是:

在你的app plist文件中添加一行,命名为“View controller-based status bar appearance”,并将其设置为NO。

edgesForExtendedLayout适用于iOS 7。然而,如果你在iOS 7 SDK上构建应用,并将其部署到iOS 6中,导航栏将显示为半透明,视图位于其下方。因此,要修复iOS 7和iOS 6的问题,请执行以下操作:

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific

我想扩展Stunner的答案,并添加一个if语句来检查它是否是iOS-7,因为当我在iOS 6上测试它时,我的应用程序会崩溃。

增加的内容是:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

我建议把这个方法添加到你的myviewcontroller中。m文件:

- (void) viewDidLayoutSubviews {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
    }
}

Swift 3 / Swift 4解决方案,也适用于iOS 10+中的nib /XIB文件:

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}