iOS程序限制:';在容器层次结构中找不到视图';

iOS程序限制:';在容器层次结构中找不到视图';,ios,objective-c,autolayout,constraints,Ios,Objective C,Autolayout,Constraints,我的iOS自定义UITableViewCell需要以下布局: |具有基本信息的视图|矩形视图的长列表| 因此,结构如下。我有一个水平滚动的滚动视图,我有“信息容器视图”在左边,矩形视图列表应该出现在信息容器的右边。自定义UITableViewCell为o 我试图添加以下约束: [self.scrollView addConstraints:[NSLayoutConstraint constraintsWi

我的iOS自定义UITableViewCell需要以下布局:

|具有基本信息的视图|矩形视图的长列表|

因此,结构如下。我有一个水平滚动的滚动视图,我有“信息容器视图”在左边,矩形视图列表应该出现在信息容器的右边。自定义UITableViewCell为o

我试图添加以下约束:

[self.scrollView addConstraints:[NSLayoutConstraint
                                             constraintsWithVisualFormat:[NSString stringWithFormat:@"H:[info]-space-[%@]", key]
                                             options:0 metrics:metrics
                                             views:viewsDictionary]];
其中info是“信息容器”,key是指动态添加的视图。这将导致以下错误:

2015-01-21 16:37:44.603 AirCourts[3264:1553444] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x174a83840 H:[UIView:0x17018f970]-(20)-[FieldSlotView:0x1701bebc0]>
Constraint: <NSLayoutConstraint:0x174a83840 H:[UIView:0x17018f970]-(20)-[FieldSlotView:0x1701bebc0]>
(...)
View not found in container hierarchy: <UIView: 0x17018f970; frame = (0 0; 320 568); autoresize = RM+BM; layer = <CALayer: 0x170e37c20>>
That view's superview: NO SUPERVIEW
2015-01-21 16:37:44.603空中法庭[3264:1553444]视图层次结构未为约束做好准备:
约束条件:
(...)
在容器层次结构中找不到视图:
该视图是superview:无superview
因此,它似乎是指“信息容器”没有superview这一事实。因此,我决定测试它:

如您所见,它并不是scrollview的后代。鉴于IB层次结构似乎是正确的,为什么会发生这种情况?我是否需要在添加约束之前刷新布局,或者它是否丢失了层次结构信息


提前谢谢

在我看来,之所以会出现这种错误,是因为“动态加载视图”不是
scrollView
的直接子对象,而是
infoView
的直接子对象

因此,为了让AutoLayout在这里工作,您最好将该约束附加到它的父视图,它应该是
infoView
,而不是
scrollView

从日志中可以看到,您的infoView是
[UIView:0x17018f970]
,AutoLayout试图在其层次结构下找到您的
[FieldSlotView:0x1701bebc0]
。这就是为什么在容器层次结构中找不到以下错误
视图:

小小费

将约束附加到视图时,可以在约束字符串中作为
|
访问该视图。因此,如果您将代码替换为

[self.infoView addConstraints:[NSLayoutConstraint
                                             constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-space-[%@]", key]
                                             options:0 metrics:metrics
                                             views:viewsDictionary]];

您可以将
[info]
替换为
|
;)

对于iOS 8.0+,苹果建议更安全的做法是简单地激活/停用约束。它们将处理受影响的视图

比如说你已经声明了

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *constraintProperty;
然后在代码中的某个地方:

[_constraintProperty setActive:NO];

// create constraint here

[NSLayoutConstraint activateConstraints:@[_constraintProperty]];
请参阅文档中的讨论:


嗨,迈克,谢谢你的回复!我的想法是,动态视图(我们称之为“字段”)是infoView的兄弟。实际上,我使用infoView可以说“字段”在布局方面将位于infoView的右侧(因此存在该约束)。您是否在viewDidLoad中检查子代控制器?您应该在ViewDidLayoutSubviews中或之后调用它,而不是在此之前。