向添加到 UIWindow 的视图添加约束时,为啥无法设置自动布局约束?

Posted

技术标签:

【中文标题】向添加到 UIWindow 的视图添加约束时,为啥无法设置自动布局约束?【英文标题】:Why am I unable to set Auto Layout constraints when adding constraints to a view I added to UIWindow?向添加到 UIWindow 的视图添加约束时,为什么无法设置自动布局约束? 【发布时间】:2013-12-07 05:04:27 【问题描述】:

为了在屏幕上创建一个深色覆盖,我在 UIWindow 上添加了一个覆盖所有其他视图的视图:

UIView *darkOverlayView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
darkOverlayView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.85];

然后我想在新的darkOverlayView 中居中一个 UIImageView,并尝试如下:

UIImageView *imageFromLink = [[UIImageView alloc] initWithImage:responseObject];
imageFromLink.translatesAutoresizingMaskIntoConstraints = NO;
            CGFloat widerThanHeightBy = imageFromLink.bounds.size.width / imageFromLink.bounds.size.height;

[darkOverlayView addConstraint:[NSLayoutConstraint constraintWithItem:imageFromLink attribute:NSLayoutAttributeWidth relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[UIScreen mainScreen].bounds.size.width]];
[darkOverlayView addConstraint:[NSLayoutConstraint constraintWithItem:imageFromLink attribute:NSLayoutAttributeHeight relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[UIScreen mainScreen].bounds.size.height / widerThanHeightBy]];

但每次运行时,我都会收到错误消息:

视图层次结构没有为约束做好准备: 添加到视图时,约束的项必须是该视图(或视图本身)的后代。如果在组装视图层次结构之前需要解决约束,这将崩溃。中断 -[UIView _viewHierarchyUnpreparedForConstraint:] 进行调试。 2013-12-07 00:59:03.626 Jupiter [58008:70b] 视图层次结构没有为约束做好准备。 约束: 容器层次结构: > 在容器层次结构中找不到视图:> - (null) 该视图的超级视图:NO SUPERVIEW

我将如何解决这个问题?还是我必须使用框架?

【问题讨论】:

【参考方案1】:

怎么说@rdelmar:

首先:你在哪里添加你的imageFromLink 比如 addSubView 到 superview?

第二: 你的限制:

[darkOverlayView addConstraint:[NSLayoutConstraint constraintWithItem:imageFromLink attribute:NSLayoutAttributeWidth relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[UIScreen mainScreen].bounds.size.width]];
[darkOverlayView addConstraint:[NSLayoutConstraint constraintWithItem:imageFromLink attribute:NSLayoutAttributeHeight relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:[UIScreen mainScreen].bounds.size.height / widerThanHeightBy]];

只设置Widthheightxy

只需再添加两个约束:

[darkOverlayView addConstraint:[NSLayoutConstraint constraintWithItem:imageFromLink attribute:NSLayoutAttributeCenterX relatedBy:0 toItem:darkOverlayView attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
[darkOverlayView addConstraint:[NSLayoutConstraint constraintWithItem:imageFromLink attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:darkOverlayView attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]];

它设置在darkOverlayView的中心。

【讨论】:

【参考方案2】:

向涉及两个视图的视图添加约束时,一个视图必须是另一个视图的子视图,因此您需要在添加约束之前将 imageFromLink 添加为 darkOverLayView 的子视图。但是,在这种情况下,您要添加宽度和高度约束,这些约束应添加到 imageFromLink,而不是其父视图。这种固定宽度或高度的约束不涉及任何其他视图,所以它应该属于视图本身,而不是父视图。

但是,添加高度和宽度约束不会使其在其父视图中居中。您还需要(在使 imageFromLink 成为子视图之后)向 darkOverlayView 添加 centerX 和 centerY 约束。

【讨论】:

以上是关于向添加到 UIWindow 的视图添加约束时,为啥无法设置自动布局约束?的主要内容,如果未能解决你的问题,请参考以下文章

我应该将底部工作表作为子视图添加到当前视图控制器还是推送添加了子视图的 UIWindow?

将 UIView 添加到 UIWindow 的子视图时未检测到画外音

UIWindow addSubview 处理事件

以编程方式向 Swift 中的视图添加约束时出错

当我使用自动布局移动视图时,为啥 XCode 5 没有在情节提要中添加约束

向底部锚添加约束是向超级视图底部添加约束