iOS 程序约束:“在容器层次结构中找不到视图”
Posted
技术标签:
【中文标题】iOS 程序约束:“在容器层次结构中找不到视图”【英文标题】:iOS Programatic Constraints: 'View not found in container hierarchy' 【发布时间】:2015-01-21 17:12:19 【问题描述】:我的 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
所以,它似乎是指“信息容器”没有超级视图的事实。因此,我决定对其进行测试:
如您所见,它不被假定为滚动视图的后代。鉴于 IB 层次结构似乎是正确的,为什么会发生这种情况?由于某种原因,我是否需要在添加约束之前刷新布局,或者它是否会丢失层次结构信息?
提前致谢!
【问题讨论】:
您是否在 viewDidLoad 中检查后代控制器?您应该在 ViewDidLayoutSubviews 或之后调用它,而不是在此之前。 【参考方案1】:在我看来,您收到该错误是因为“动态加载的视图”不是scrollView
的直接子代,而是infoView
的直接子代。
因此,为了让 AutoLayout 在这里工作,您宁愿将该约束附加到它的父视图,它应该是 infoView
,而不是 scrollView
。
从日志中可以看出,您的 infoView 是 [UIView:0x17018f970]
,AutoLayout 会尝试在其层次结构下找到您的 [FieldSlotView:0x1701bebc0]
。这就是为什么您会收到以下错误View not found in container hierarchy: <UIView: 0x17018f970>
小提示
将约束附加到视图时,您可以在约束字符串中以|
的形式访问它。因此,如果您将代码替换为
[self.infoView addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:[NSString stringWithFormat:@"H:|-space-[%@]", key]
options:0 metrics:metrics
views:viewsDictionary]];
您可以将[info]
替换为|
;)
【讨论】:
嗨,迈克,感谢您的回复!我的想法是动态视图(我们称它们为“字段”)是 infoView 的兄弟姐妹。实际上,我使用 infoView 能够说“字段”在布局方面将位于 infoView 的右侧(因此受到限制)。【参考方案2】:对于 iOS 8.0+,Apple 建议简单地激活/停用约束更安全。他们将处理受影响的视图。
比如说你已经声明了
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *constraintProperty;
然后在你的代码中的某个地方:
[_constraintProperty setActive:NO];
// create constraint here
[NSLayoutConstraint activateConstraints:@[_constraintProperty]];
参见文档中的讨论:
https://developer.apple.com/documentation/uikit/uiview/1622513-addconstraints https://developer.apple.com/documentation/uikit/uiview/1622659-removeconstraint
【讨论】:
以上是关于iOS 程序约束:“在容器层次结构中找不到视图”的主要内容,如果未能解决你的问题,请参考以下文章
堆栈视图中的自动约束冲突、Swift 2、iOS 9.3、XCode 7
XCode 6.4 中 iOS8 Storyboard 中缺少约束图标,适用于最初在早期版本的 iOS 下编写的应用程序