状态栏和导航栏出现在 iOS 7 中我的视图边界上
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17074365/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Status bar and navigation bar appear over my view's bounds in iOS 7
提问by beebcon
I recently downloaded Xcode5 DP to test my apps in iOS 7. The first thing I noticed and confirmed is that my view's bounds is not always resized to account for the status bar and navigation bar.
我最近下载了Xcode5 DP 来在 iOS 7 中测试我的应用程序。我注意到并确认的第一件事是我的视图边界并不总是调整大小以考虑状态栏和导航栏。
In viewDidLayoutSubviews
, I print the view's bounds:
在 中viewDidLayoutSubviews
,我打印视图的边界:
{{0, 0}, {320, 568}}
{{0, 0}, {320, 568}}
This results in my content appearing below the navigation bar and status bar.
这导致我的内容出现在导航栏和状态栏下方。
I know I could account for the height myself by getting the main screen's height, subtracting the status bar's height and navigation bar's height, but that seems like unnecessary extra work.
我知道我可以通过获取主屏幕的高度、减去状态栏的高度和导航栏的高度来自己计算高度,但这似乎是不必要的额外工作。
How can I fix this issue?
我该如何解决这个问题?
Update:
更新:
I've found a solution for this specific problem. Set the navigation bar's translucent property to NO:
我已经找到了解决这个特定问题的方法。将导航栏的半透明属性设置为 NO:
self.navigationController.navigationBar.translucent = NO;
This will fix the view from being framed underneath the navigation bar and status bar.
这将修复视图被框在导航栏和状态栏下方。
However, I have not found a fix for the case when you want the navigation bar to be translucent. For instance, viewing a photo full screen, I wish to have the navigation bar translucent, and the view to be framed underneath it. That works, but when I toggle showing/hiding the navigation bar, I've experienced even stranger results. The first subview (a UIScrollView) gets its bounds y origin changed every time.
但是,当您希望导航栏半透明时,我还没有找到解决方法。例如,在全屏查看照片时,我希望导航栏是半透明的,并且视图在其下方被框起来。这有效,但是当我切换显示/隐藏导航栏时,我遇到了更奇怪的结果。第一个子视图(一个 UIScrollView)每次都改变它的边界 y 原点。
回答by Nandha
You can achieve this by implementing a new property called edgesForExtendedLayout
in iOS7 SDK. Please add the following code to achieve this,
您可以通过实现edgesForExtendedLayout
在 iOS7 SDK 中调用的新属性来实现这一点。请添加以下代码以实现此目的,
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
You need to add the above in your -(void)viewDidLoad
method.
您需要在您的-(void)viewDidLoad
方法中添加上述内容。
iOS 7 brings several changes to how you layout and customize the appearance of your UI. The changes in view-controller layout, tint color, and font affect all the UIKitobjects in your app. In addition, enhancements to gesture recognizer APIs give you finer grained control over gesture interactions.
Using View Controllers
In iOS 7, view controllers use full-screen layout. At the same time, iOS 7 gives you more granular control over the way a view controller lays out its views. In particular, the concept of full-screen layout has been refined to let a view controller specify the layout of each edge of its view.
The
wantsFullScreenLayout
view controller property is deprecated in iOS 7. If you currently specifywantsFullScreenLayout = NO
, the view controller may display its content at an unexpected screen location when it runs in iOS 7.To adjust how a view controller lays out its views,
UIViewController
provides the following properties:
- edgesForExtendedLayout
The
edgesForExtendedLayout
property uses theUIRectEdge
type, which specifies each of a rectangle's four edges, in addition to specifying none and all. UseedgesForExtendedLayout
to specify which edges of a view should be extended, regardless of bar translucency. By default, the value of this property isUIRectEdgeAll
.
- extendedLayoutIncludesOpaqueBars
If your design uses opaque bars, refine
edgesForExtendedLayout
by also setting theextendedLayoutIncludesOpaqueBars
property to NO. (The default value ofextendedLayoutIncludesOpaqueBars
is NO.)
- automaticallyAdjustsScrollViewInsets
If you don't want a scroll view's content insets to be automatically adjusted, set
automaticallyAdjustsScrollViewInsets
to NO. (The default value ofautomaticallyAdjustsScrollViewInsets
is YES.)
- topLayoutGuide, bottomLayoutGuide
The
topLayoutGuide
andbottomLayoutGuide
properties indicate the location of the top or bottom bar edges in a view controller's view. If bars should overlap the top or bottom of a view, you can use Interface Builder to position the view relative to the bar by creating constraints to the bottom oftopLayoutGuide
or to the top of bottomLayoutGuide. (If no bars should overlap the view, the bottom oftopLayoutGuide
is the same as the top of the view and the top ofbottomLayoutGuide
is the same as the bottom of the view.) Both properties are lazily created when requested.
iOS 7 对您布局和自定义UI外观的方式进行了多项更改。视图控制器布局、色调和字体的变化会影响应用中的所有UIKit对象。此外,手势识别器 API 的增强使您可以更精细地控制手势交互。
使用视图控制器
在 iOS 7 中,视图控制器使用全屏布局。同时,iOS 7 使您可以更精细地控制视图控制器布局其视图的方式。特别是,全屏布局的概念已经被细化,让视图控制器指定其视图每个边缘的布局。
该
wantsFullScreenLayout
视图控制器属性在iOS的7弃用如果您目前指定wantsFullScreenLayout = NO
,当它在iOS的7运行视图控制器可显示其在一个意想不到的画面位置的内容。要调整视图控制器布局其视图的方式,请
UIViewController
提供以下属性:
- edgeForExtendedLayout
除了指定 none 和 all 外,该
edgesForExtendedLayout
属性还使用UIRectEdge
类型,该类型指定矩形的四个边中的每一个。使用edgesForExtendedLayout
来指定一个视图的边缘应该扩展,而不管杆半透明的。默认情况下,此属性的值为UIRectEdgeAll
。
- extendedLayoutIncludesOpaqueBars
如果您的设计使用不透明条,请
edgesForExtendedLayout
同时将该extendedLayoutIncludesOpaqueBars
属性设置为 NO 进行优化。(的默认值extendedLayoutIncludesOpaqueBars
是NO。)
- 自动调整ScrollViewInsets
如果您不想自动调整滚动视图的内容插入,请设置
automaticallyAdjustsScrollViewInsets
为NO。(的默认值automaticallyAdjustsScrollViewInsets
是YES)。
- 顶部布局指南、底部布局指南
的
topLayoutGuide
和bottomLayoutGuide
特性指示的顶部或底部边缘条的视图中的控制器的视图中的位置。如果条形图应该与视图的顶部或底部重叠,您可以使用 Interface Builder 通过topLayoutGuide
在 bottomLayoutGuide的底部或顶部创建约束来相对于条形图定位视图。(如果没有与视图重叠的条形,则底部topLayoutGuide
与视图顶部相同,顶部与视图bottomLayoutGuide
底部相同。)这两个属性都是在请求时延迟创建的。
Please refer, apple doc
请参考,苹果文档
回答by Mick MacCallum
You don't have to calculate how far to shift everything down, there's a build in property for this. In Interface Builder, highlight your view controller, and then navigate to the attributes inspector. Here you'll see some check boxes next to the words "Extend Edges". As you can see, in the first screenshot, the default selection is for content to appear under top and bottom bars, but not under opaque bars, which is why setting the bar style to not translucent worked for you.
您不必计算将所有内容向下移动多远,为此有一个内置属性。在 Interface Builder 中,突出显示您的视图控制器,然后导航到属性检查器。在这里,您会在“扩展边”字样旁边看到一些复选框。如您所见,在第一个屏幕截图中,默认选择是让内容显示在顶部和底部栏下方,而不是出现在不透明栏下方,这就是将栏样式设置为不透明的原因。
As you can somewhat see in the first screenshot, there are two UI elements hiding below the navigation bar. (I've enabled wireframes in IB to illustrate this) These elements, a UIButton and a UISegmentedControl both have their "y" origin set to zero, and the view controller is set to allow content below the top bar.
正如您在第一个屏幕截图中所看到的,导航栏下方隐藏着两个 UI 元素。(我在 IB 中启用了线框来说明这一点)这些元素,一个 UIButton 和一个 UISegmentedControl 都将它们的“y”原点设置为零,并且视图控制器设置为允许顶部栏下方的内容。
This second screenshot shows what happens when you deselect the "Under Top Bars" check box. As you can see, the view controllers view has been shifted down appropriately for its y origin to be right underneath the navigation bar.
第二个屏幕截图显示了取消选中“Under Top Bars”复选框时会发生的情况。如您所见,视图控制器视图已适当向下移动,使其 y 原点位于导航栏正下方。
This can also be accomplished programmatically through the usage of -[UIViewController edgesForExtendedLayout]
. Here's a link to the class reference for edgeForExtendedLayout, and for UIRectEdge
这也可以通过使用-[UIViewController edgesForExtendedLayout]
. 这是edgeForExtendedLayout和UIRectEdge类参考的链接
[self setEdgesForExtendedLayout:UIRectEdgeNone];
回答by Stunner
I created my view programmatically and this ended up working for me:
我以编程方式创建了我的视图,这最终对我有用:
- (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;
}
}
Source(in topLayoutGuidesection at bottom of pg.39).
来源(在第39 页底部的 topLayoutGuide 部分)。
回答by flo_23
Swift 3 / Swift 4 solution that also works with NIBs/XIB files in iOS 10+:
Swift 3 / Swift 4 解决方案也适用于 iOS 10+ 中的 NIB/XIB 文件:
override func viewDidLoad() {
super.viewDidLoad()
edgesForExtendedLayout = []
}
回答by Magnus
If you want the view to have the translucent nav bar (which is kind of nice) you have to setup a contentInset or similar.
如果您希望视图具有半透明导航栏(这很好),您必须设置 contentInset 或类似内容。
Here is how I do it:
这是我如何做到的:
// 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);
}
回答by Raj Pawan Gumdal
edgesForExtendedLayout
does the trick for iOS 7. However, if you build the app across iOS 7 SDK and deploy it in iOS 6, the navigation bar appears translucent and the views go beneath it. So, to fix it for both iOS 7 as well as for iOS 6 do this:
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
回答by Idan
In your apps plist file add a row, call it "View controller-based status bar appearance" and set it to NO.
在您的应用程序 plist 文件中添加一行,将其命名为“基于控制器的状态栏外观”并将其设置为NO。
回答by Riskov
The simplest trick is to open the NIBfile and do these two simple steps:
最简单的技巧是打开NIB文件并执行以下两个简单步骤:
- Just toggle that and set it to the one you prefer:
- 只需切换它并将其设置为您喜欢的那个:
- Select those UIView's/UIIMageView's/... that you want to be moved down. In my case only the logo was overlapped an I've set the delta to +15; (OR -15 if you chose iOS 7 in step 1)
- 选择那些你想向下移动的 UIView's/UIIMageView's/...。在我的情况下,只有徽标重叠,我已将增量设置为 +15;(如果您在步骤 1 中选择了 iOS 7,则为 -15)
And the result:
而结果:
回答by fatihyildizhan
Swift Solution:
迅捷解决方案:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.edgesForExtendedLayout = UIRectEdge.None
}
回答by werdsackjon
I would like to expand on Stunner's answer, and add an if
statement to check if it is iOS-7, because when I tested it on iOS 6 my app would crash.
我想扩展 Stunner 的答案,并添加一个if
语句来检查它是否是 iOS-7,因为当我在 iOS 6 上测试它时,我的应用程序会崩溃。
The addition would be adding:
添加将添加:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
So I would suggest adding this method to your MyViewControler.m
file:
所以我建议将此方法添加到您的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;
}
}