使用自动布局将子视图添加到 UITableView 不会设置其框架

Posted

技术标签:

【中文标题】使用自动布局将子视图添加到 UITableView 不会设置其框架【英文标题】:Adding subview to UITableView with autolayout doesn't set its frame 【发布时间】:2016-08-15 13:32:59 【问题描述】:

我正在使用以下代码向视图添加覆盖视图:

UIView *overlayView = [[UIView alloc] init];
overlayView.backgroundColor = [UIColor redColor];

[self.view addSubview:overlayView];

overlayView.translatesAutoresizingMaskIntoConstraints = NO;
NSDictionary *views = NSDictionaryOfVariableBindings(overlayView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[overlayView]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[overlayView]|" options:0 metrics:nil views:views]];

如果我将此代码放在UIViewControllerviewDidLoad 方法中,它可以正常工作。但是,如果我在 UITableViewController 中执行相同操作,则覆盖视图将获得零帧。

我已经检查了视图,我可以确定约束确实被正确添加并且它们处于活动状态。但由于某些原因,它们似乎被忽略了。

我没有收到任何错误或警告。

我在这里错过了什么?

PS:我知道我可以用self.view.bounds 作为框架来实例化覆盖视图,它可以工作。但是,我需要使用自动布局。

【问题讨论】:

【参考方案1】:

怀疑这是因为 UITableView 是 UIScrollView 并且在使用建立自己的边界系统的视图(例如滚动视图或表格视图)时,自动布局有一些注意事项。

在覆盖视图上设置的约束是这样的,它被约束到滚动视图的顶部、右侧、底部和左侧边缘,因此被约束到滚动视图的内容区域而不是滚动视图的框架。

看 https://developer.apple.com/library/ios/technotes/tn2154/_index.html 和Auto Layout Guide: Working with Scroll Views:

滚动视图的边缘或边距与其 内容附加到滚动视图的内容区域。

与其将覆盖视图约束到内容区域,不如将其约束到滚动视图的框架。根据上面的参考资料,这可以通过将覆盖视图的宽度/高度约束到滚动视图来完成,或者通过将覆盖视图约束到滚动视图之外的视图来完成。

【讨论】:

是的,我认为它是这样的。我确实以其他方式解决了它,但我更希望能够使用自动布局。 在 iOS 11 中可以使用 table view 的 frameLayoutGuide 属性。

以上是关于使用自动布局将子视图添加到 UITableView 不会设置其框架的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式使用自动布局将子视图添加到 UICollectionView 不起作用

由于自动布局没有计算尺寸,将子视图添加到自定义视图最终会出错

将子视图添加到 UINavigationBar 时向下推 UITableView

ios 将子视图添加到不在中心的 ScrollView

将子视图添加到 UITable

使用自动布局强制 UITableView 中的 UIView 填满屏幕