在 iOS 应用程序中添加自动布局子视图时高度错误

Posted

技术标签:

【中文标题】在 iOS 应用程序中添加自动布局子视图时高度错误【英文标题】:Wrong height when adding autolayout subview in iOS app 【发布时间】:2014-10-10 12:46:11 【问题描述】:

我正在尝试将子视图添加到现有视图。我基本上是在添加一个子视图来模仿这个例子的 ActionSheet:

http://cocoaallocinit.com/2014/03/23/implementing-a-custom-uiactionsheet

只要我不在自定义 ActionSheet 上使用自动布局,此示例就可以正常工作。当我这样做时,我会遇到一些问题。我添加的子视图由一个红色视图组成。此红色视图对其高度、水平和垂直空间有限制。

(来源:bildr.no)

我的问题是 4S 和 5S 设备上的高度似乎不正确。 5S 的视野比 4S 高。我预计它会反过来,因为 5S 比 4S 有更多的积分。

(来源:bildr.no)

我用这段代码添加子视图:

[self.view addSubview:self.customActionSheet.view]; [self.customActionSheet viewWillAppear:NO];

如果我改为通过推送来添加视图:

[self.navigationController pushViewController:self.customActionSheet animated:YES];

然后结果就像我预期的那样。 4S完全被红视图覆盖,5S在红视图上方仍有部分区域。

我在这里做错了什么?

【问题讨论】:

你是在使用自动布局还是自动调整大小 【参考方案1】:

您的视图不会根据设备屏幕自动调整大小。 [UINavigationController pushViewController: animated:] 将起作用,因为导航控制器为您设置了视图的框架。快速的方法是将视图的框架设置为当前视图。

self.customActionSheet.view.frame = self.view.bounds;

并且不要自己调用viewWillAppear:,系统会调用它。

我的建议是使用自动布局来满足您对 superview 的看法。以下代码使用 PureLayout:https://github.com/smileyborg/PureLayout

[self.view addSubview:self.customActionSheet.view]
[self.customActionSheet.view autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];

【讨论】:

【参考方案2】:

问题是你需要给self.customActionSheet.view添加约束。

当您通过pushViewController:animated: 消息加载控制器视图时,系统会为视图添加所需的约束,使其填充所有屏幕空间。

相反,如果您手动添加它(通过addSubview: 消息),自动布局约束不会自动创建,您需要以编程方式创建它们并将它们添加到视图中。

我在这里发布一个您可能需要的示例,以便您 customActionSheet 填满所有屏幕空间:

NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:self.view
                                                                      attribute:NSLayoutAttributeLeft
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:self.customActionSheet.view
                                                                      attribute:NSLayoutAttributeLeft
                                                                     multiplier:1.0
                                                                       constant:0];

NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:self.view
                                                                      attribute:NSLayoutAttributeTop
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:self.customActionSheet.view
                                                                      attribute:NSLayoutAttributeTop
                                                                     multiplier:1.0
                                                                       constant:0];

NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:self.view
                                                                      attribute:NSLayoutAttributeBottom
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:self.customActionSheet.view
                                                                      attribute:NSLayoutAttributeBottom
                                                                     multiplier:1.0
                                                                       constant:0];


NSLayoutConstraint *right = [NSLayoutConstraint constraintWithItem:self.view
                                                                  attribute:NSLayoutAttributeRight
                                                                  relatedBy:NSLayoutRelationEqual
                                                                     toItem:self.customActionSheet.view
                                                                  attribute:NSLayoutAttributeRight
                                                                 multiplier:1.0
                                                                   constant:0];

[self.view addSubview:self.customActionSheet.view];
[self.view addConstraints:@[left, right, top, bottom]];

【讨论】:

约束已添加到 xib 文件中。很抱歉没有解释。

以上是关于在 iOS 应用程序中添加自动布局子视图时高度错误的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将自动布局约束添加到恒定宽度和高度的子视图

如何使用自动布局根据子视图调整父视图的高度

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

如何使用自动布局动态更改超级视图的高度

在自动布局的情况下,IOS scrollview 模糊的可滚动内容高度

在水平堆栈视图(自动布局)中将文本与图像垂直居中 - iOS