以编程方式设置自动布局约束

Posted

技术标签:

【中文标题】以编程方式设置自动布局约束【英文标题】:Set autolayout constraints programmatically 【发布时间】:2015-12-26 04:26:52 【问题描述】:

我不知道如何解决这个问题:我想创建一个匹配游戏,其中卡片的大小取决于设备。

我想我会创建一个 contentView,我将其固定到 rootView 的顶部和底部,边距为 20,并将其对齐到它的中心。然后我给它一个 3/4 的纵横比(3 行 4 列)。

let contentView = UIView()
// place contentView on the view
self.view.addSubview(contentView)
contentView.translatesAutoresizingMaskIntoConstraints = false

//add position constraints to thecontentView
let topMargin = NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 20)
let bottomMargin = NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: -20)

let horzontalAllignment = NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)
let verticalAllignment = NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)

self.view.addConstraints([topMargin, bottomMargin, horzontalAllignment, verticalAllignment])

//  create an aspect ratio for the contentView
let aspect = NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.Height, multiplier: 4/3, constant: 0)
contentView.addConstraint(aspect)

效果很好。 (哇哦!)然后我想创建一个卡片,其宽度为 contentView 的四分之一,高度为三分之一:

let thisCard = Card()
contentView.addSubview(thisCard)
thisCard.translatesAutoresizingMaskIntoConstraints = false

let hightConstraint = NSLayoutConstraint(item: thisCard, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.Height, multiplier: 1/3, constant: 0)

let widthConstraint = NSLayoutConstraint(item: thisCard, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: contentView, attribute: NSLayoutAttribute.Width, multiplier: 1/4, constant: 0)

thisCard.addConstraints([hightConstraint, widthConstraint])

代码中断,我收到消息:

视图层次结构没有为约束做好准备: NSLayoutConstraint:0x78f1b290 Meeres_Memo_temp_caseinsensitive_renamery.Card:0x78f41820.height == UIView:0x78f49fc0.height 添加到视图时,约束的项目 必须是该视图(或视图本身)的后代。这会崩溃 如果在视图层次结构之前需要解决约束 组装好了。

有没有可能,做我想做的事?

更新:

我刚刚发现我的错误。 我在 thisCard 中添加了 heightConstraint 和 widthConstraint,但需要将它们添加到视图层次结构中较高的相关视图,在本例中为 contentView,如下所示:

contentView.addConstraints([hightConstraint, widthConstraint])

【问题讨论】:

查看这个库,它可以帮助您以编程方式解决约束。 github.com/PureLayout/PureLayout 【参考方案1】:

阅读错误信息。如果项目位于同一视图层次结构中,则只能添加约束。我认为您尝试在将 thisCard 或 contentView 添加到视图层次结构之前添加约束。你需要先这样做。

顺便说一句。 1/4 不是你想的那样——它是一个大胖子零。 1/4 使用整数除法。例如,使用 1.0 / 4。

【讨论】:

你能澄清一下吗?我将 contenView 添加为 rootview 的子视图,并将卡片添加为 contentView 的子视图(在上面的代码中)。我还有什么需要做的吗?

以上是关于以编程方式设置自动布局约束的主要内容,如果未能解决你的问题,请参考以下文章

ObjC,在以编程方式添加/删除后恢复为界面构建器自动布局约束?

为编程视图层次结构设置自动布局约束?

使用自动布局以编程方式调整标签宽度

模糊自动布局约束(以编程方式添加)

如何在 ios swift 中以编程方式创建自动布局等宽约束?

自动布局 - 以编程方式定义异常约束