在iOS 7中,状态栏和导航栏出现在我的视图's边界上

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

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

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

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

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

我该如何解决这个问题?

更新:

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

self.navigationController.navigationBar.translucent = NO;

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

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

219396 次浏览

如果你想让视图有半透明的导航栏(这很好),你必须设置一个contentInset或类似的。

我是这样做的:

// Check if we are running on ios7
if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7) {
CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame];
float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height;


myContentView.contentInset = UIEdgeInsetsMake(heightPadding, 0.0, 0.0, 0.0);
}

你可以通过在iOS7 SDK中实现一个名为edgesForExtendedLayout的新属性来实现这一点。请添加以下代码来实现此功能,

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;

您需要在-(void)viewDidLoad方法中添加上述内容。

iOS 7带来了一些改变,如何布局和自定义 用户界面的外观。视图-控制器布局,色调的变化 颜色和字体会影响应用程序中的所有UIKit对象 此外,增强的手势识别器api给你更好的 对手势交互的粒度控制。< / p >

使用视图控制器

在ios7中,视图控制器使用全屏布局。与此同时, iOS 7在视图控制器的方式上给了你更细粒度的控制 显示视图。特别是全屏布局的概念 已经被细化到让一个视图控制器指定每个的布局

中的wantsFullScreenLayout视图控制器属性已弃用 iOS 7。如果当前指定wantsFullScreenLayout = NO,则视图 控制器可能会在意外的屏幕位置显示其内容

UIViewController用于调整视图控制器如何布局其视图

  • edgesForExtendedLayout
edgesForExtendedLayout属性使用UIRectEdge类型, 它指定矩形的四条边,除了 指定none和all。使用edgesForExtendedLayout来指定 视图的边缘应该被扩展,不管条的透明度如何。通过 默认情况下,此属性的值为UIRectEdgeAll
  • extendedLayoutIncludesOpaqueBars
如果你的设计使用不透明条,细化edgesForExtendedLayout by 还将extendedLayoutIncludesOpaqueBars属性设置为 没有> < /强。(extendedLayoutIncludesOpaqueBars的默认值是没有。)

  • automaticallyAdjustsScrollViewInsets

如果你不希望滚动视图的内容插入自动 调整后,设置automaticallyAdjustsScrollViewInsets没有。( automaticallyAdjustsScrollViewInsets的默认值是是的)

  • topLayoutGuide, bottomLayoutGuide

topLayoutGuidebottomLayoutGuide属性表示 视图控制器视图中顶部或底部栏边的位置。 如果条应该重叠视图的顶部或底部,您可以使用 接口构建器来定位视图相对于条通过创建 的底部或顶部 bottomLayoutGuide。(如果没有条应重叠视图,底部 topLayoutGuide与视图的顶部和的顶部相同 bottomLayoutGuide与视图的底部相同。)这两个

请参考苹果医生

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

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

enter image description here

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

enter image description here

这也可以通过使用-[UIViewController edgesForExtendedLayout]以编程方式完成。下面是edgeForExtendedLayoutUIRectEdge类引用的链接

[self setEdgesForExtendedLayout:UIRectEdgeNone];

在你的app plist文件中添加一行,称为“基于视图控制器的状态栏外观”,并将其设置为没有

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

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

Enter image description here

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

Enter image description here

结果:

Before . < img src = " https://i.stack.imgur.com/jpKpY.png " alt = "后" > < / p >

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

从下拉列表中添加键“基于视图控制器的状态栏外观”作为info.plist中的一行。就像这样:

Enter image description here

我以编程方式创建了我的视图,这最终为我工作:

- (void) viewDidLayoutSubviews {
// only works for iOS 7+
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect viewBounds = self.view.bounds;
CGFloat topBarOffset = self.topLayoutGuide.length;


// snaps the view under the status bar (iOS 6 style)
viewBounds.origin.y = topBarOffset * -1;


// shrink the bounds of your view to compensate for the offset
viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
self.view.bounds = viewBounds;
}
}

(在pg.39底部的topLayoutGuide部分)。

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

增加的内容是:

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

所以我建议将这个方法添加到你的MyViewControler.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;
}
}

对我来说,最简单的解决方案是在plist中添加两个键

enter image description here

我有一个场景,我使用苹果编写的BannerViewController来显示我的广告和嵌入在BannerViewController中的ScrollViewController。

为了防止导航栏隐藏我的内容,我必须做两个更改。

1)修改BannerViewController.m

- (void)viewDidLoad
{
[super viewDidLoad];
float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
}

2)修改我的scrollviewcontroller

- (void)viewDidLoad
{
[super viewDidLoad];
float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (systemVersion >= 7.0) {
self.edgesForExtendedLayout = UIRectEdgeBottom;
}
}

现在广告正确地显示在视图的底部,而不是被导航栏覆盖,顶部的内容也没有被切断。

隐藏状态栏的步骤:

1.转到您的应用程序信息。plist文件。

2.和设置,查看基于控制器的状态栏外观:布尔NO

希望我解决了状态栏问题.....

我在ipad (armv7, armv7s, amr64)上的应用程序也有同样的问题,只是通过呈现另一个UIViewController,并在驳回它们后在状态栏下的导航栏… 我花了很多时间来寻找解决方案。我使用故事板和在InterfaceBuilder的UIViewController,这使得糟糕的我设置从全屏->当前上下文的演示,它修复了这个问题。它在我的应用程序只适用于ipad => iOS8.0(测试与iOS8.1)和ipad与iOS 7.1不工作!!see screen

只要在视图中设置以下代码就会出现。

  if ([[[UIDevice currentDevice] systemVersion] floatValue]<= 7) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}

迅速的解决方案:

override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.edgesForExtendedLayout = UIRectEdge.None
}
对顶部布局做一个约束,如下所示 enter image description here < / p >

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

override func viewDidLoad() {
super.viewDidLoad()


edgesForExtendedLayout = []
}
在我的情况下,loadView()中断
这段代码: 自我。edgesForExtendedLayout = UIRectEdgeNone

但删除loadView()后一切工作正常

斯威夫特3

override func viewWillAppear(_ animated: Bool) {
self.edgesForExtendedLayout = []
}

Swift 4.2 - Xcode 10.0 - iOS 12.0:

if #available(iOS 11.0, *) {} else {
self.edgesForExtendedLayout = []
self.navigationController?.view.backgroundColor = .white
}