将子视图的X置于自动布局中将引发“未准备好约束”
我有一个自定义的UIView子类正在通过一个笔尖初始化。
在-awakeFromNib
,我创build了一个子视图,并尝试将它置于其超视图中。
[self setInteralView: [[UIView alloc] init]]; [[self internalView] addConstraint: [NSLayoutConstraint constraintWithItem: [self internalView] attribute: NSLayoutAttributeCenterX relatedBy: NSLayoutRelationEqual toItem: self attribute: NSLayoutAttributeCenterX multiplier: 1 constant: 0]];
这打破了,并导致以下输出:
2013-08-11 17:58:29.628 MyApp[32414:a0b] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0xc1dcc80 UIView:0xc132a40.centerX == MyView:0xc1315a0.centerX> When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled. Break on -[UIView _viewHierarchyUnpreparedForConstraint:] to debug. 2013-08-11 17:58:29.630 MyApp[32414:a0b] View hierarchy unprepared for constraint. Constraint: <NSLayoutConstraint:0xc1dcc80 UIView:0xc132a40.centerX == MyView:0xc1315a0.centerX> Container hierarchy: <UIView: 0xc132a40; frame = (0 0; 0 0); clipsToBounds = YES; layer = <CALayer: 0xc132bc0>> View not found in container hierarchy: <MyView: 0xc1315a0; frame = (-128 -118; 576 804); layer = <CALayer: 0xc131710>> That view's superview: <UIView: 0xc131a70; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0xc131b50>>
由于错误状态,您必须将约束添加到视图,以使约束中涉及的视图是您要添加的视图或该视图的子视图。 在上面的代码中,你应该把自己的约束添加到self
,而不是[self internalView]
。 如果你只考虑[self internalView]
和下面的内容,那么它不能以书面forms工作的原因是约束( self
)中包含的视图之一不在视图层次结构中。
有关更多详细信息,请参阅addConstraint:
方法文档的讨论部分 。
这是你的代码行,我build议修正:
UIView* internalView = [[UIView alloc] initWithFrame:CGRectZero]; internalView.translatesAutoresizingMaskIntoConstraints = NO; [self setInternalView:internalView]; [self addConstraint: [NSLayoutConstraint constraintWithItem: [self internalMapView] attribute: NSLayoutAttributeCenterX relatedBy: NSLayoutRelationEqual toItem: self attribute: NSLayoutAttributeCenterX multiplier: 1 constant: 0]];
对于来这里的其他人:我得到了这个错误,因为我在添加子视图到层次结构之前添加了约束条件。
简短的回答 : 交换父母和孩子的看法。
假设self
是父视图:
-
不好 :
[subview addConstraint [NSLayoutConstraint constraintWithItem:self...
-
好 :
[self addConstraint [NSLayoutConstraint constraintWithItem:subview...
迅速
subview.translatesAutoresizingMaskIntoConstraints = false self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat( "H:|-0-[subview]-0-|", options: .DirectionLeadingToTrailing, metrics: nil, views: ["subview":subview]))
OBJ-C
[subview setTranslatesAutoresizingMaskIntoConstraints:NO]; [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[subview]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(subview)]];
其他提示:
我有一个新开发的应用程序在iOS7上运行良好,但在iOS8上出现错误“视图层次结构没有为约束准备”。
读一些其他职位说,(子)视图需要添加之前创build约束。 我这样做,但仍然有错误。
然后我发现我应该在 – (void)viewDidAppear而不是viewDidLoad下创build约束
正如@CharlesA在他的回答中指出的那样,问题在于你添加的视图不在正确的视图层次结构中。 他的回答是一个很好的答案,但是我要详细介绍一个特定的用例,这个用例对我造成了这个问题:
当试图向我使用instantiateViewControllerWithIdentifier
的视图控制器添加约束时,发生了这种情况。 为了解决这个问题,我使用了[childViewController didMoveToParentViewController:self]
。 这将视图添加到由我的约束引用的视图层次结构中。
这是一个老问题,但我想从文档中指出这一行:
在为iOS 8.0或更高版本开发时,将约束的isActive属性设置为true,而不是直接调用addConstraint(_ :)方法。 isActive属性自动添加并从正确的视图中删除约束。
至less,这将消除一个故障点,因为您不再需要担心在错误的视图上调用addConstraint