21

我有一个去年构建的项目,它使用 XIB,没有故事板。XIB 不使用 Auto Layout,但它们确实使用了一些 Autosizing。使用 iOS7 运行时出现问题,其中所有视图都隐藏在状态栏下。我完全理解这是 iOS7 的一个新功能,这是可以预料的。但是,所有修复它以使其不这样做的解决方案都不起作用。我在视图顶部有一个始终显示在状态栏下的图像,并且我没有使用导航栏或类似的东西。

我尝试过更新 XIB 中的 Y-deltas(它们对视图没有影响),我尝试过将其设置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);

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

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

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

提前致谢!

4

7 回答 7

17

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

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

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

我所做的是在 Interface Builder 中向超级视图添加顶部空间约束,并在代码中为此创建了一个出口。然后,在 viewDidLoad 中,如果 topLayoutGuide 可用(iOS 7+),则将此插座中的约束替换为使用 Top Layout Guide 的版本。

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];
}
于 2013-10-01T12:47:58.153 回答
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];
    }
}
于 2013-09-24T20:00:38.927 回答
5

Apple 正在推动您使用自动布局来完成此操作。您需要从视图的顶部子视图中为“顶部布局指南”设置约束。

有关示例,请参阅此文档:

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

这方面的文档可以UIViewController类参考中找到。

于 2013-10-08T08:08:08.040 回答
3

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

self.navigationController.navigationBar.translucent = NO;

2)svguerin3 的答案在一般情况下不起作用。例如,如果您的其中一个子视图使用自动调整大小来钩在其容器的底部,那么它的新位置将是错误的。在最坏的情况下,它可能会出现在屏幕之外。

于 2013-10-08T19:51:42.777 回答
2
- (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);
}
于 2014-05-06T06:25:18.180 回答
0

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

我们不得不在故事板的场景中删除这条线,因为我们的故事板场景的主要视图由 XIB 表示

对我们来说,不知何故,在某些场景中,场景主视图的 XIB 内容被状态栏和导航栏的高度压低了。

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

可悲的是,我们不知道是什么触发了这个,但我看到它发生在更改 XIB 主视图中的内容顺序时,以便 UITextView 首先出现。在触发此事件后重新排列项目的顺序对消除这种不需要的行为没有任何影响。

希望这可以帮助其他遇到此类问题的人。

于 2014-07-07T21:35:15.193 回答
0

如果您正在使用情节提要,在设置视图的顶部布局后,您可以在属性检查器中取消选中“不透明条下”

故事板

于 2017-09-21T06:14:03.323 回答