简体   繁体   中英

Set autolayout constraints programmatically

I can't figure out how to fix this: I want to create a match game, where the size of the cards depends on the device.

I thought I would create a contentView which I pinned to top and bottom of the rootView with a margin of 20 and alligned it to its center. Then I give it an aspect ratio of 3/4 (for 3 rows and 4 columns).

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)

That works perfectly. (Whohoo!) Then I want to create a card that has a quarter of the contentView width and a third of the hight:

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])

There the code breaks and I get the message:

The view hierarchy is not prepared for the constraint: NSLayoutConstraint:0x78f1b290 Meeres_Memo_temp_caseinsensitive_renamery.Card:0x78f41820.height == UIView:0x78f49fc0.height When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled.

Is it even possible, to do want I want to?

Update:

I just found my error. I added the heightConstraint and widthConstraint to thisCard, but they need to be added to the the related view that is higher in the view hierarchy, in this case the contentView, like this:

contentView.addConstraints([hightConstraint, widthConstraint])

Read the error message. You can only add constraints if the items are in the same view hierarchy. I would think that you tried to add the constraints before either thisCard or contentView were added to a view hierarchy. You need to do that first.

BTW. 1/4 is not what you think - it is a big fat zero. 1/4 uses integer division. Use 1.0 / 4, for example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM