首页 文章

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

提问于
浏览
20

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

我已经尝试更新XIB中的Y-delta(它们对视图没有影响),我已经尝试将 edgesForExtendedLayout 设置为 UIRectEdgeNone (什么都不做),还有很多其他的东西 . 每次,状态栏显示隐藏在它下面的视图,无论我做什么...这是除非我手动向下移动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);

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

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

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

提前致谢!

7 回答

  • 0

    如果在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];
    }
    
  • 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];
        }
    }
    
  • 3

    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];
    

    可以在in the UIViewController class reference找到相关文档 .

  • 2

    1)如果你不介意有一个不透明的导航栏,最简单的解决方案:

    self.navigationController.navigationBar.translucent = NO;
    

    2)svguerin3的答案在一般情况下不起作用 . 例如,如果您的某个子视图使用自动调整大小挂钩到其容器的底部,则其新位置将是错误的 . 它可能会在最坏的情况下走出屏幕案件 .

  • 17
    - (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);
    }
    
  • 5

    您是否尝试将XIB视为源并删除包含edgesforextendedlayout的任何行?

    我们必须在故事板的场景中删除这一行,因为我们的故事板的场景主要视图由XIB表示

    我们发生的事情是,不知何故,在某些场景中,场景主视图的XIB内容被状态栏和导航栏的高度向下推 .

    删除该行允许显示XIB,就好像它们的顶部始于其故事板场景的同一顶部 .

    遗憾的是,我们不知道是什么引发了这种情况,但我发现在更改XIB主视图中内容的顺序时会发生这种情况,因此首先出现UITextView . 触发此项后,重新排列项目的顺序对删除此不需要的行为没有任何影响 .

    希望这有助于其他任何人遇到此类问题 .

  • 0

    如果您正在使用故事板,则在设置视图的顶部布局后,可以取消选中“属性”检查器中的“不透明条形图”

    Storyboard

相关问题