ios iOS7 - 在状态栏下查看 -edgesForExtendedLayout 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18990224/
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
iOS7 - View under status bar - edgesForExtendedLayout not working
提问by svguerin3
I have a project that was built last year, and it uses XIBs, no storyboards. The XIBs do not use Auto Layout, but they do use some Autosizing. I have an issue when running with iOS7, in which all the views are tucked under the status bar. I fully understand this is a new feature with iOS7, in which this can be expected. However, all of the solutions for fixing it to not do this are not working. I have an image at the top of the view that always shows under the status-bar, and I'm not using nav-bars or anything like that.
我有一个去年建立的项目,它使用 XIB,没有故事板。XIB 不使用自动布局,但它们使用一些自动调整大小。我在运行 iOS7 时遇到一个问题,其中所有视图都隐藏在状态栏下。我完全理解这是 iOS7 的一个新功能,这是可以预料的。但是,修复它以不执行此操作的所有解决方案都不起作用。我在视图顶部有一个图像,它总是显示在状态栏下,我没有使用导航栏或类似的东西。
I have tried updating the Y-deltas in the XIB (they have no effect on the view), I have tried setting the edgesForExtendedLayout
to UIRectEdgeNone
(does nothing), and a multitude of other things. Every time, the status bar shows with the view tucked under it, no matter what I do.. that is unless I manually move down the view in the XIB to allow room for the status bar (but that solution doesn't work because it doesn't look right in iOS6, of course).
我尝试更新 XIB 中的 Y 增量(它们对视图没有影响),我尝试将其设置edgesForExtendedLayout
为UIRectEdgeNone
(什么都不做),以及许多其他事情。每次,无论我做什么,状态栏都会显示隐藏在其下方的视图......除非我手动向下移动 XIB 中的视图以为状态栏留出空间(但该解决方案不起作用,因为它当然,在 iOS6 中看起来不正确)。
What's odd is that even when I try a line of code to hack in a view-shift, it doesn't work (like the following):
奇怪的是,即使我尝试使用一行代码在视图转换中进行 hack,它也不起作用(如下所示):
self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+20, self.view.frame.size.width, self.view.frame.size.height);
..Not that I would go with that kind of solution, but it's just odd that it didn't work (the only time I typically see that not work is if Auto Layout is in place, which it's not in this case).
..并不是说我会采用那种解决方案,但奇怪的是它不起作用(我通常看到的唯一一次不起作用是如果自动布局到位,在这种情况下不是)。
It is a design requirement that the status-bar shows, and I'm just stumped on why I can't set the view to be under the status bar for iOS7. I have read every single Stack Overflow post on the subject, as well as Apple's transition/guides. Once again, to reiterate, I fully understand how it should function and what the expected solution should be to this, but none of that seems to be working for this particular project.
这是状态栏显示的设计要求,我只是为为什么我不能将视图设置为 iOS7 的状态栏下而感到困惑。我已经阅读了有关该主题的每一篇 Stack Overflow 帖子,以及 Apple 的转换/指南。再次重申,我完全理解它应该如何运作以及预期的解决方案应该是什么,但这些似乎都不适用于这个特定项目。
I am an experienced iOS dev, but this project was built by another team, so I don't know if there's something hidden somewhere in the XIB files, plist, or code that could be trumping the above settings. Please let me know if there is something else that can be looked at on this, or more information I can provide.
我是一名经验丰富的 iOS 开发人员,但这个项目是由另一个团队构建的,所以我不知道在 XIB 文件、plist 或代码中是否有隐藏的东西可以胜过上述设置。请让我知道是否还有其他可以查看的内容,或者我可以提供的更多信息。
Thanks in advance!
提前致谢!
采纳答案by Kim André Sand
If you set the iOS 6/7 delta values in Interface Builder, remember to set "View as" to "iOS 6" on the Interface Builder Document, since it is the iOS 6 layout you want to replicate. The deltas will then be used only on iOS 7 to push the content below the status bar. If you leave "View as" set to iOS 7 (the default) the deltas will instead give you the iOS 7 look on iOS 6.
如果您在 Interface Builder 中设置 iOS 6/7 delta 值,请记住在 Interface Builder Document 上将“View as”设置为“iOS 6”,因为它是您要复制的 iOS 6 布局。然后增量将仅在 iOS 7 上用于将内容推送到状态栏下方。如果您将“查看为”设置为 iOS 7(默认),增量将改为在 iOS 6 上为您提供 iOS 7 外观。
However, the deltas will not help you if you reposition or resize views programmatically based on the view frame, since the frame does not account for the deltas.
但是,如果您根据视图框架以编程方式重新定位或调整视图大小,则增量将无济于事,因为该框架不考虑增量。
Instead of using the deltas, the best solution I have found is to enable Auto Layout on your main XIB and then set the top space constraint on your top/content view to follow the Top Layout Guide. This guide was introduced in iOS 7 and represents the position below the status bar. Unfortunately the guide is not available in Interface Builder when not using Storyboards, but you can add it programmatically.
我发现的最佳解决方案不是使用增量,而是在主 XIB 上启用自动布局,然后在顶部/内容视图上设置顶部空间约束以遵循顶部布局指南。本指南是在 iOS 7 中引入的,表示状态栏下方的位置。不幸的是,当不使用 Storyboards 时,该指南在 Interface Builder 中不可用,但您可以通过编程方式添加它。
What I did was add a top space constraint to the superview instead in Interface Builder, and created an outlet for this in the code. Then, in viewDidLoad, if the topLayoutGuide is available (iOS 7+), replace the constraint in this outlet with a version using the Top Layout Guide instead.
我所做的是在界面生成器中向超级视图添加顶部空间约束,并在代码中为此创建了一个出口。然后,在 viewDidLoad 中,如果 topLayoutGuide 可用(iOS 7+),请使用使用 Top Layout Guide 的版本替换此 outlet 中的约束。
if ([self respondsToSelector:@selector(topLayoutGuide)]) {
[self.view removeConstraint:self.containerTopSpaceConstraint];
self.containerTopSpaceConstraint =
[NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.topLayoutGuide
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0];
[self.view addConstraint:self.containerTopSpaceConstraint];
[self.view setNeedsUpdateConstraints];
[self.view layoutIfNeeded];
}
回答by svguerin3
For reference, the solution below did work when I applied it to my ViewControllers. However, it's not ideal and a bit hacky. If it's the only approach I can take, then so be it, though.
作为参考,当我将下面的解决方案应用于我的 ViewControllers 时,它确实有效。然而,这并不理想,而且有点老套。如果这是我可以采取的唯一方法,那么就这样吧,不过。
float systemVersion=[[[UIDevice currentDevice] systemVersion] floatValue];
if(systemVersion>=7.0f)
{
CGRect tempRect;
for(UIView *sub in [[self view] subviews])
{
tempRect = [sub frame];
tempRect.origin.y += 20.0f; //Height of status bar
[sub setFrame:tempRect];
}
}
回答by petehare
Apple are pushing you to use autolayout to accomplish this. You need to set a constraint to the "Top Layout Guide" from the top subview in your view.
Apple 正在推动您使用自动布局来实现这一点。您需要在视图的顶部子视图中为“顶部布局指南”设置约束。
See this document for examples:
有关示例,请参阅此文档:
https://developer.apple.com/library/ios/qa/qa1797/_index.html
https://developer.apple.com/library/ios/qa/qa1797/_index.html
To do this without XIBs, you'll need to add the constraint programatically. Apple's docs give a good example of this, which I've summarised below.
要在没有 XIB 的情况下执行此操作,您需要以编程方式添加约束。Apple 的文档给出了一个很好的例子,我在下面进行了总结。
Giving that the topLayoutGuide
is a property on a view controller, you just use it in your dictionary of variable bindings. Then you set up your constraint like normal:
假设topLayoutGuide
是视图控制器上的一个属性,您只需在变量绑定字典中使用它。然后像往常一样设置约束:
id topGuide = [myViewController topLayoutGuide];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(button, topGuide);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-20-[button]" options:0 metrics:nil views:viewsDictionary];
The documentation for this can be found in the UIViewController
class reference.
相关文档可以在UIViewController
类参考中找到。
回答by Aurelien Porte
1)The simplest solution if you don't mind having an opaque navigation bar:
1)如果你不介意有一个不透明的导航栏,最简单的解决方案:
self.navigationController.navigationBar.translucent = NO;
2) svguerin3's answer can't work in the general case. For example, if one of your subviews uses autosizing to be hooked at the bottom of its container, then its new position will be wrong. And it could go out of screen in the worst case.
2) svguerin3 的答案在一般情况下不起作用。例如,如果您的子视图之一使用 autosizing 挂钩在其容器底部,则其新位置将是错误的。在最坏的情况下,它可能会退出屏幕。
回答by Mazen Kasser
- (void)viewDidAppear:(BOOL)animated {
[self.view setFrame:CGRectMake(0, 20, self.view.frame.size.width, self.view.frame.size.height)];
// OR
self.view.transform = CGAffineTransformMakeTranslation(0, 20);
}
回答by Alex Zavatone
Have you tried viewing your XIBs as source and removing any line containing ?edgesforextendedlayout ??
您是否尝试将您的 XIB 视为源并删除任何包含 ?edgesforextendedlayout 的行?
We had to remove this line in our storyboard's scenes since our storyboard's scenes' main views are represented by XIBs
我们不得不在我们的故事板场景中删除这一行,因为我们的故事板场景的主要视图由 XIB 表示
What was happening for us was that somehow, in some scenes, the XIB content for the scene's main view was being pushed down by the height of the status bar and the navigation bar.
对我们来说发生的事情是不知何故,在某些场景中,场景主视图的 XIB 内容被状态栏和导航栏的高度下推。
Removing that line allowed the XIBs to be displayed as if their top originated at the same top of its storyboard's scene.
删除该行允许显示 XIB,就好像它们的顶部起源于其故事板场景的同一顶部。
Sadly, we have no idea what triggered this, but I saw it happen when changing the order of the contents within the XIB's main view so that a UITextView appeared first. Rearranging the order of items after this was triggered had no effect in removing this unwanted behaviour.
遗憾的是,我们不知道是什么触发了这个,但我看到它发生在改变 XIB 主视图中的内容顺序时,以便首先出现 UITextView。在触发此事件后重新排列项目的顺序对消除这种不需要的行为没有影响。
Hope this helps anyone else running into this type of problem.
希望这可以帮助其他任何遇到此类问题的人。
回答by dhin
If you are using the storyboard, after setting the top layout of your view, you can uncheck the "Under Opaque Bars" in the Attributes Inspector
如果您正在使用故事板,在设置视图的顶部布局后,您可以取消选中属性检查器中的“Under Opaque Bars”