ios7 - iOS 7状态栏和导航栏显示于视图边界

  显示原文与译文双语对照的内容

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

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

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

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

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

我该如何解决此问题?

更新:

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


self.navigationController.navigationBar.translucent = NO;

这将把视图固定在导航栏和状态栏下面。

但是,当你希望导航栏半透明时,我没有找到一个修复。 例如查看一张全屏屏幕,我想让导航栏半透明,并将视图放在它下面。 这很有用,但是当我切换显示/隐藏导航栏的时候,我甚至遇到了一些奇怪的结果。 第一个 subview ( UIScrollView ) 得到了它的边界,每次都改变。

时间:

你可以通过在 web sphere edgesForExtendedLayout 中实现一个名为的新属性来实现这一点。 请添加以下代码以实现这里目的,


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

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

iOS 7为你展示了如何布局和自定义你的 UI界面的外观。 view-controller布局,淡色和字体的变化会影响你应用中的所有对象。 此外,对手势识别api的增强给手势交互提供了更好的粒度控制。

使用视图控制器

在 iOS 7中,视图控制器使用full-screen布局。 同时,iOS 7为你提供了更细粒度的控制视图控制器布局的方式。 特别是,full-screen布局的概念已经被细化,以允许视图控制器指定它的视图的每个边缘的布局。

wantsFullScreenLayout 7中不推荐使用视图控制器属性。 如果你当前指定了 wantsFullScreenLayout = NO,那么当你在 iOS 7中运行时,视图控制器可能会在意外的屏幕位置显示它的内容。

为了调整视图控制器布局视图的方式,UIViewController 提供了以下属性:

  • edgesForExtendedLayout

edgesForExtendedLayout 属性使用 UIRectEdge 类型,它指定矩形边的每一个,除了指定无和全部。 使用 edgesForExtendedLayout 指定应该扩展视图的哪些边,而不考虑条形透明度。 默认情况下,这里属性的值为 UIRectEdgeAll

  • extendedLayoutIncludesOpaqueBars

如果你的设计使用了不透明的栏,请将 edgesForExtendedLayoutextendedLayoutIncludesOpaqueBars 属性设置为磅 no 。 ( extendedLayoutIncludesOpaqueBars的默认值为 。)

  • automaticallyAdjustsScrollViewInsets

如果不想自动调整滚动内容的滚动内容,请设置 automaticallyAdjustsScrollViewInsets没有。(默认值 automaticallyAdjustsScrollViewInsets is是 yes 。

  • topLayoutGuide,bottomLayoutGuide

topLayoutGuidebottomLayoutGuide 属性表示控制器视图中顶部或者底部栏边缘的位置。 如果部分应重叠的顶部或者底部使用一个视图中,可以使用界面构建器将视图相对于定位线通过创建限制,topLayoutGuide的底部或者以bottomLayoutGuide的顶端的。 ( 如果没有栏重叠视图,topLayoutGuide的底部与视图的顶部相同,bottomLayoutGuide的顶部与视图的顶部相同。) 两个属性在请求时被延迟创建。

请参考,doc文档

你不需要计算多少转变一切,有一个建立在财产。 在界面生成器中,高亮显示你的视图控制器,然后导航到属性检查器。 在这里,你将看到单词"扩展边缘"旁边的一些复选框。 正如你所看到的,在第一个截图,内容的默认选择是出现在顶部和底部的酒吧,但不是在不透明的酒吧,这就是为什么设置栏样式不透明的为你工作。

就像你在第一个屏幕截图中看到的,在导航栏下面有两个用户界面元素。 (我使线框ib说明这)这些元素,UIButton和UISegmentedControl都"y"原点设置为0,和下面的视图控制器设置为允许内容窗口的顶部。

enter image description here

第二个屏幕截图显示取消选中"在顶部栏之下"复选框时发生的情况。 正如你所看到的,视图控制器的视图已经转移了适当的导航栏下面y起源是正确的。

enter image description here

这也可以通过使用以下方法通过编程方式实现 -[UIViewController edgesForExtendedLayout] 下面是指向 edgeForExtendedLayout 类的类引用和 UIRectEdge标题的链接


[self setEdgesForExtendedLayout:UIRectEdgeNone];

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


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

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

如果你想让视图具有半透明导航栏( 这是一种很好的),你必须设置一个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);
}

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

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

  1. 只需切换并将它的设置为你喜欢的:

Enter image description here

  1. 选择要向下移动的UIView's/UIIMageView's/... 。 在我的例子中,只有 logo 被重叠为 +15,我将增量设置为;( 或者,如果你选择了第 -15步中的iOS 7 )

Enter image description here

结果 :

BeforeAfter

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

添加将添加:


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

所以我建议将这个方法添加到你的MyViewControler.m file:


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

我有一个情况我使用BannerViewController由苹果显示广告和 BannerViewController ScrollViewController嵌入。

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

1 ) 修改 BannerViewController.m


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

2 ) 修改我的ScrollViewContoller


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

现在的广告也能正确的显示在底部视图,而不是由顶部导航栏和内容不是切断。

...