iOS7 - 状态栏下的视图 - edgesForExtendedLayout无法正常工作

svg*_*in3 20 iphone xcode objective-c ios ios7

我有一个去年建成的项目,它使用XIB,没有故事板.XIB不使用自动布局,但它们确实使用了一些自动调整大小.运行iOS7时出现问题,其中所有视图都隐藏在状态栏下.我完全理解这是iOS7的新功能,可以预期这一点.但是,所有用于修复它的解决方案都不起作用.我在视图顶部有一个图像,它总是显示在状态栏下面,我没有使用导航栏或类似的东西.

我已经尝试更新XIB中的Y-delta(它们对视图没有影响),我已经尝试设置edgesForExtendedLayoutUIRectEdgeNone(什么都不做),还有很多其他的东西.每次状态栏都显示隐藏在它下面的视图,无论我做什么......除非我手动向下移动XIB中的视图以留出状态栏的空间(但该解决方案不起作用,因为它当然,在iOS6中看起来并不正确.

奇怪的是,即使我尝试使用一行代码来破解视图移位,它也不起作用(如下所示):

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);
Run Code Online (Sandbox Code Playgroud)

..不是我会采用那种解决方案,但奇怪的是它不起作用(我通常看到不起作用的唯一一次是自动布局是否到位,在这种情况下不是这样).

这是状态栏显示的设计要求,我只是难以理解为什么我无法将视图设置为iOS7的状态栏.我已阅读有关该主题的每个Stack Overflow帖子,以及Apple的过渡/指南.再一次,重申一下,我完全理解它应该如何运作以及预期的解决方案应该是什么,但这些似乎都不适用于这个特定的项目.

我是一个经验丰富的iOS开发人员,但是这个项目是由另一个团队构建的,所以我不知道是否有某些东西隐藏在XIB文件,plist或代码中,可能超过上述设置.如果有其他可以查看的内容,或者我可以提供更多信息,请告诉我.

提前致谢!

Kim*_*and 17

如果在Interface Builder中设置iOS 6/7 delta值,请记住在Interface Builder Document上将"View as"设置为"iOS 6",因为它是要复制的iOS 6布局.然后,仅在iOS 7上使用增量将内容推送到状态栏下方.如果将"查看为"设置为iOS 7(默认设置),则增量将在iOS 6上为您提供iOS 7外观.

但是,如果基于视图框架以编程方式重新定位视图或调整视图大小,则增量将无法帮助您,因为框架不考虑增量.

我找到的最佳解决方案是在主XIB上启用自动布局,然后在顶部/内容视图上设置顶部空间约束,以遵循顶部布局指南,而不是使用增量.本指南在iOS 7中引入,代表状态栏下方的位置.遗憾的是,当不使用Storyboard时,Interface Builder中没有该指南,但您可以通过编程方式添加它.

我所做的是在界面生成器中向superview添加顶部空间约束,并在代码中为此创建了一个插座.然后,在viewDidLoad中,如果topLayoutGuide可用(iOS 7+),请使用"顶部布局指南"替换此插座中的约束.

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];
}
Run Code Online (Sandbox Code Playgroud)


svg*_*in3 6

作为参考,当我将它应用于我的ViewControllers时,下面的解决方案确实有效.然而,它并不理想,有点hacky.如果这是我能采取的唯一方法,那么就这样吧.

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];
    }
}
Run Code Online (Sandbox Code Playgroud)


pet*_*are 5

Apple正在推动您使用autolayout来实现这一目标.您需要在视图的顶部子视图中为"顶部布局指南"设置约束.

请参阅此文档以获取示例:

https://developer.apple.com/library/ios/qa/qa1797/_index.html

要在没有XIB的情况下执行此操作,您需要以编程方式添加约束.Apple的文档给出了一个很好的例子,我在下面总结了这一点.

如果它topLayoutGuide是视图控制器上的属性,则只需在变量绑定的字典中使用它.然后像普通一样设置约束:

id topGuide = [myViewController topLayoutGuide];
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(button, topGuide);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-20-[button]" options:0 metrics:nil views:viewsDictionary]; 
Run Code Online (Sandbox Code Playgroud)

可以UIViewController类引用中找到相关文档.