2

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])
Myriam
  • 73
  • 8
  • Check out this library, it might help you with constraints programatically. https://github.com/PureLayout/PureLayout –  Sep 28 '15 at 20:35

1 Answers1

0

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.

gnasher729
  • 47,695
  • 5
  • 65
  • 91
  • Could you clarify that? I added the contenView as a subview of the rootview and the card as a subview to the contentView (in the code above). Is there something else I need to do? – Myriam Sep 29 '15 at 10:45