ios 在自动布局中居中子视图的 X 抛出“未准备好约束”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18177262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Centering subview's X in autolayout throws "not prepared for the constraint"
提问by Patrick Perini
I have a custom UIView subclass which is being initialized via a nib.
我有一个通过笔尖初始化的自定义 UIView 子类。
In -awakeFromNib
, I'm creating a subview and attempting to center it in its superview.
在 中-awakeFromNib
,我正在创建一个子视图并尝试将其置于其超级视图中。
[self setInteralView: [[UIView alloc] init]];
[[self internalView] addConstraint: [NSLayoutConstraint constraintWithItem: [self internalView]
attribute: NSLayoutAttributeCenterX
relatedBy: NSLayoutRelationEqual
toItem: self
attribute: NSLayoutAttributeCenterX
multiplier: 1
constant: 0]];
This breaks, and causes the following output:
这会中断,并导致以下输出:
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>>
回答by Jannie Theunissen
For others who come here: I got this error, because I added the constraints before I added the subviews to the hierarchy.
对于来到这里的其他人:我收到此错误,因为我在将子视图添加到层次结构之前添加了约束。
回答by Charles A.
As the error states, you must add the constraint to a view such that the views involved in the constraint are the view you're adding it to or a subview of that view. In the case of your code above, you should be adding that constraint to self
, rather than [self internalView]
. The reason it doesn't work as written is one of the views involved in the constraint (self
) is not in the view hierarchy if you consider only [self internalView]
and below).
作为错误状态,您必须将约束添加到视图中,以便约束中涉及的视图是您将其添加到的视图或该视图的子视图。对于上面的代码,您应该将该约束添加到self
,而不是[self internalView]
。它不能按所写的方式工作的原因是约束中涉及的视图之一 ( self
) 不在视图层次结构中,如果您只考虑[self internalView]
以下内容)。
For more details, see the discussion section of the documentationon the addConstraint:
method.
有关更多详细信息,请参阅有关该方法的文档的讨论部分addConstraint:
。
Here is your line of code, fixed as I suggest:
这是您的代码行,按照我的建议进行修复:
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]];
回答by SwiftArchitect
Short answer: swapparent and child view.
Assuming self
is the parent view:
简短回答:交换父视图和子视图。
假设self
是父视图:
bad:
[subview addConstraint [NSLayoutConstraint constraintWithItem:self...
good:
[self addConstraint [NSLayoutConstraint constraintWithItem:subview...
坏:
[subview addConstraint [NSLayoutConstraint constraintWithItem:self...
好:
[self addConstraint [NSLayoutConstraint constraintWithItem:subview...
Swift
迅速
subview.translatesAutoresizingMaskIntoConstraints = false
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-0-[subview]-0-|",
options: .DirectionLeadingToTrailing,
metrics: nil,
views: ["subview":subview]))
Obj-C
对象-C
[subview setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"H:|-0-[subview]-0-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:NSDictionaryOfVariableBindings(subview)]];
回答by Kevin
Additional Tips:
附加提示:
I have a newly developed App which running fine on iOS7 but get error on iOS8 "The view hierarchy is not prepared for the constraint".
我有一个新开发的应用程序,它在 iOS7 上运行良好,但在 iOS8 上出现错误“视图层次结构未为约束做好准备”。
Read some other post said that the (sub)views need to be added before create constraints. I did that but still got the error.
阅读其他一些帖子说在创建约束之前需要添加(子)视图。我这样做了,但仍然出现错误。
Then I figured out that I should create constraints under -(void)viewDidAppear instead of viewDidLoad
然后我发现我应该在 -(void)viewDidAppear 而不是 viewDidLoad 下创建约束
回答by WongWray
This is an old question but I want to point out this line from the docs:
这是一个老问题,但我想从文档中指出这一行:
When developing for iOS 8.0 or later, set the constraint's isActive property to true instead of calling the addConstraint(_:) method directly. The isActive property automatically adds and removes the constraint from the correct view.
在为 iOS 8.0 或更高版本开发时,将约束的 isActive 属性设置为 true,而不是直接调用 addConstraint(_:) 方法。isActive 属性会自动从正确的视图中添加和删除约束。
At the very least, this will remove one point of failure since you no longer need to worry about calling addConstraint on the wrong view
至少,这将消除一点故障,因为您不再需要担心在错误的视图上调用 addConstraint
回答by Vyacheslav
In my case, it was solved by using root view as a container of constraints instead of a currently created view.
就我而言,它是通过使用根视图作为约束容器而不是当前创建的视图来解决的。
I mean, use inside viewController
我的意思是,在 viewController 中使用
view.addConstraints([leftConstraintImage, topConstraintImage])
instead of imageView.addConstraints...
view.addConstraints([leftConstraintImage, topConstraintImage])
代替 imageView.addConstraints...
回答by benvolioT
As @CharlesA points out in his answer the problem is that the view you are adding is not in the proper view hierarchy. His answer is a good one, but I'm going to throw in some detail for a particular use-case that caused this problem for me:
正如@CharlesA 在他的回答中指出的,问题在于您添加的视图不在正确的视图层次结构中。他的回答很好,但我将针对导致我出现此问题的特定用例提供一些详细信息:
I had this happen when attempting to add constraints to a view whose view controller I had instantiated using instantiateViewControllerWithIdentifier
. To solve the problem, I used [childViewController didMoveToParentViewController:self]
. This added the view into the view hierarchy that was referenced by my constraint.
我在尝试向视图添加约束时发生了这种情况,我已经使用instantiateViewControllerWithIdentifier
. 为了解决这个问题,我使用了[childViewController didMoveToParentViewController:self]
. 这将视图添加到我的约束引用的视图层次结构中。
回答by oskarko
First add your subView and then add your constraints like this
首先添加您的子视图,然后像这样添加您的约束
addSubview(yourSubViewHere)
yourSubViewHere.translatesAutoresizingMaskIntoConstraints = false
addConstraint(NSLayoutConstraint(....