i would like to place three View in following layout:
ImageView: II Textlabel: TT TitleLabel: TL Space: S
SSSSSS-TL-SSSSS
IISSSSTT--------------
SSSSSSSSSSSSSS
My current Code for this is as follows:
let views = ["imageView": imageView, "titleLabel": titleLabel, "messageLabel": messageLabel] as [String : Any]
var constraints = [NSLayoutConstraint]()
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[imageView]-[titleLabel]|", options: [], metrics: nil, views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-(==20@900)-[titleLabel]-(==20@900)-|", options: [], metrics: nil, views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[imageView]-[messageLabel]-(==20@900)-|", options: [], metrics: nil, views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[imageView]-(==30@200)-[titleLabel]-(==8@200)-[messageLabel]-(==30@200)-|", options: [], metrics: nil, views: views)
imageHeightConstraint = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: imageView, attribute: .height, multiplier: 0, constant: 0)
constraints.append(imageHeightConstraint!)
It works... almost fine. I'm not receiving the layout i want, but i receive an acceptable layout with a few bugs.
But the console also is reporting a few things which makes me worrying:
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. ( "", "", "", "" )
Could someone please help me? I'm not having really much experience with NSLayoutConstraints in General, specially not in Swift.
It would be great if you could help me getting the wished layout or fix the things the console want be fixed.
Thanks a lot!
Let's debug this. If you are using visual format constraints, the idea would be to have one Horizontal
and Vertical
constraints for each view. But I see you have multiple constraints for a view.
Also, remember to set translateAutoresizingMask
for each view to false
.
Let's track the constraints.
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[imageView]-[titleLabel]|", options: [], metrics: nil, views: views)
Here ImageView
and titleLabel
have 1 horizonatal contsraints. Moving ahead, I have put the total counting below.
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|-(==20@900)-[titleLabel]-(==20@900)-|", options: [], metrics: nil, views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[imageView]-[messageLabel]-(==20@900)-|", options: [], metrics: nil, views: views)
constraints += NSLayoutConstraint.constraints(withVisualFormat: "V:|[imageView]-(==30@200)-[titleLabel]-(==8@200)-[messageLabel]-(==30@200)-|", options: [], metrics: nil, views: views)
The above constraint is conflicting.
Why? because you have already declared a Vertical
constraints [ImageView - messageLabel]
and Now you are making [imageView - titleLabel - messageLabel]
.
imageHeightConstraint = NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: imageView, attribute: .height, multiplier: 0, constant: 0)
The above constraint is also of no use because you are setting the height constraints of imageView
to itself, it should be with its superview
or a constant.
Counting above, you have extra constraints lying.
ImageView: H: 1 and V: 2 // You have extra height contraitns.
titleLabel: H: 1 and V: 2
messageLabel: H: 0 and V: 1
The answer is simple, you just need one-one constraint for each. For e.g.
// ImageView contrainst
constraints += NSLayoutConstraint.constraints(withVisualFormat: "H:|[imageView]-[titleLabel]|", options: [], metrics: nil, views: views)
constraints(withVisualFormat: "V:|[imageView]-(==30@200)-[titleLabel]-(==8@200)-[messageLabel]-(==30@200)-|", options: [], metrics: nil, views: views)