Programmatic constraints creates an oversized subview

Hi,
When I apply constraints to my UIImageView, the image view's height expands larger than the area available even though I'm setting the width/height/top/trailing to its superview.
The layout is this:
- UITableViewCell
- UIScrollView
- custom UIView (xib / @IBDesignable - not sure if this is the issue)
- circleContainer (UIView) - Has constraints setup in Xcode
- circleView (UIView)
- imageView (UIImageView)
If I comment out the anchor/constraints code for imageView, the height is fine.
Do I need to call anything after setting the constraints on circleView? Any advice appreciated.

circleView.translatesAutoresizingMaskIntoConstraints = false
circleView.topAnchor.constraint(equalTo: circleContainer.topAnchor).isActive = true
circleView.heightAnchor.constraint(equalTo: circleContainer.heightAnchor).isActive = true
circleView.trailingAnchor.constraint(equalTo: circleContainer.trailingAnchor).isActive = true
circleView.widthAnchor.constraint(equalTo: circleView.heightAnchor).isActive = true
        
// imageView is the only subview of circleView
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.topAnchor.constraint(equalTo: circleView.topAnchor).isActive = true
imageView.heightAnchor.constraint(equalTo: circleView.heightAnchor).isActive = true
imageView.trailingAnchor.constraint(equalTo: circleView.trailingAnchor).isActive = true
imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor).isActive = true

Thanks in advance.

Where do you define the values (constant) for the constraints ? In IB ?


Logically, you should define the constraints :

var aConstraint : NSLayoutConstraint


aConstraint = NSLayoutConstraint(item: …, attribute: .leading, relatedBy: .equal, toItem: …, attribute: .leading, multiplier: 1.0, constant: 0)


Then declare it active

aConstraint.isActive = true

The contraints for circleContainer are set in the storyboard - top, trailing, bottom, leading.
circleView and imageView don't have any (they need to be done programmatically)/

OK, but I do not see how you build them programmatically.

Are you setting translatesAutoresizingMaskIntoConstraints *before* adding the view to your hierarchy? From what I recall, if you don’t do that it creates some constraints when you add it. In any case, use Xcode’s view debugger to see what constraints are there at runtime.

>> even though I'm setting the width/height/top/trailing to its superview


FWIW, this isn't true in the code you showed. You're setting the width to be equal to the height in both cases, which is the same thing as setting the height equal to the width. But the height is also constrained relative to the superview. That seems like conflicting constraints on the height, and I wouldn't be surprised if something is being logged about it.


You might need to use constraint priorities to determine the order in which conflicting constraints are satisfied.


I'd also suggest you watch this video from WWDC 2018:


https://developer.apple.com/videos/play/wwdc2018/220/


It has some best practices to follow that might be relevant to your situation.

Thanks for your comments everyone. There were no constraint errors being logged.
In the end I ended up ditching the programmatic constraints, used storyboard ones and used a low vertical Content Compression Resistance Priority (250) on the imageView. This worked perfect across devices.
I think the custom xib was creating the issue. There were never any constraints issues being logged. Interestingly, by swapping the UIImageView with an UIView, the original constraints code I posted worked perfectly.
Still a bit confused why a UIView would work fine instead; and why a small fix like the compression priority worked on the UIImageView 😕

This wasn't the issue, but good to know, thank you 🙂

Changing priorities has the effect that constraints that were incapitible (because at the same priority level) now become compatible, as one take the lead over the other. But that's a delicate fine tuning !


And maybe, when you changed to UIView, what you changed in fact is the order in the xib (the new view being now after or before another), which changed how constraints were handled.

Programmatic constraints creates an oversized subview
 
 
Q