如何在具有自动布局的 Interface Builder 中创建的现有视图中添加视图?

Posted

技术标签:

【中文标题】如何在具有自动布局的 Interface Builder 中创建的现有视图中添加视图?【英文标题】:How to add views in an existing view made in Interface Builder with Auto Layout? 【发布时间】:2015-03-17 04:49:43 【问题描述】:

我在 Interface Builder 中创建了以下自动布局:

如您所见,我没有为按钮提供任何固定大小。我想以编程方式添加两个按钮以获得此结果:

以编程方式添加约束我知道怎么做,至少我知道语法。

我的问题是何时创建这些按钮?

我根据按钮 4 的宽度创建宽度约束。如果我在 viewDidLoad 中执行此操作(如果我没记错的话),则尚未设置自动布局,因此宽度(和高度)将为错误的。

我想在 viewDidLayoutSubviews 中执行此操作,但由于在加载 viewController 时它被多次调用,我得到多个按钮相互堆叠,当我进入横向时添加了更多按钮..

我应该什么时候创建这些按钮以使其具有正确的尺寸?

【问题讨论】:

【参考方案1】:

自动布局是关于始终存在的规则,而不是(主要)关于任何时刻的帧大小。

当您为按钮 5 和 6 设置约束时,您不应关心获取按钮 4 的框架。为按钮 5 和 6 添加的约束应引用按钮 4 的宽度属性,而不是其当前宽度(以磅为单位) .也就是说,您可以创建这样的约束:

NSLayoutConstraint* constraint = [NSLayoutConstraint constraintWithItem:button5 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:button4 attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
constraint.active = YES; // OR: [button5.superview addConstraint:constraint]

这是一个约束,即使按钮 4 的宽度发生变化,也会使按钮 5 的宽度与按钮 4 的宽度相同。你会为高度和按钮 6 做同样的事情。等等。

换句话说,您在运行时创建的约束应该与您在设计时在 IB 中创建的约束相似。在我看来,您并没有在按钮 4 上创建明确的、固定的高度和宽度约束。您已经创建了将其高度和宽度与其他视图相关联的相对约束。

您必须做的一件事:由于按钮 2 和 4 对容器(或其边距)有尾随空间限制,因此您需要在添加按钮 5 和 6 时移除这些限制。按钮 2 和 4 将具有分别对按钮 5 和 6 具有尾随约束,并且按钮 5 和 6 必须对容器具有尾随约束。实际上,您应该通过删除按钮 4 对容器的尾随约束并将其替换为按钮 2 的尾随对齐约束来简化。同样,按钮 6 的尾沿应与按钮 5 对齐,而不是与超级视图的间隔。这样,您只需删除一个约束(按钮 2 的尾随到 superview)并添加一个(按钮 5 的尾随到 superview)。

【讨论】:

非常感谢!我实际上使用的是let button_constraint_H:Array = NSLayoutConstraint.constraintsWithVisualFormat("H:[container500(width)]", options: NSLayoutFormatOptions(0), metrics: metricsDictionary, views: viewsDictionary),其中width 来自button.bounds.width。所以在我的情况下使用constraintsWithVisualFormat 是不可能的?关于删除约束,我如何删除我在 IB 中创建的一个特定约束,因为约束(或标签)没有 id?我是否必须将它们全部删除,然后只创建所需的(那时并不实际)。再次感谢 如果您将按钮 4 作为视图之一传入,则可以使用可视格式语言:H:[button5(==button4)]。要删除约束,您可以创建一个出口并将其连接到 IB,就像任何其他出口一样。例如,打开 Assistant 编辑器以显示您的控制器类并按住 Control 键从 IB 中的约束拖动到您的控制器类并创建出口。 没有意识到你可以做一个有约束的插座。再次感谢!【参考方案2】:

您可以在viewDidLoad 中以编程方式创建约束。如果您为按钮创建了IBOutlet,那么您可以访问它们并获得如下大小:

self.myButton.frame.size.height;

您可以使用Autolayout Constraints 工具来简化此过程。

【讨论】:

当我在 viewDidLoad 中执行此操作时,我实际上得到了错误的尺寸,而我从 viewDidLayoutSubviews 中获得了正确的尺寸。感谢您的链接

以上是关于如何在具有自动布局的 Interface Builder 中创建的现有视图中添加视图?的主要内容,如果未能解决你的问题,请参考以下文章

转 iOS 8 Auto Layout界面自动布局系列2-使用Xcode的Interface Builder添加布局约束

在 Interface Builder 中删除自动布局(约束)

Interface Builder 中的相对自动布局约束

与在 Interface Builder 中使用自动布局相比,SnapKit 有啥优势?

Interface Builder 自动布局和调整大小

Xcode Interface builder 中的 Nib 视图不应用自动布局约束