5

I have a button inside a view. I have set image for my button in interface builder. The constraints that I have added to my button in interface builder is:

Right space to superview = 10

top space to superview = 10

bottom space to superview >= 10

left space to a label >= 10

All thing work fine and I have no problem with my layout. But when I log the button constraints with this code:

NSLog(@"constraints for btnBack is: %@", self.btnBack.constraints);

the console logs:

constraints for btnBack is:(

"<NSContentSizeLayoutConstraint:0x7c35c400 H:[UIButton:0x7c3588a0(102)] Hug:250 CompressionResistance:750>"

"<NSContentSizeLayoutConstraint:0x7c35c450 V:[UIButton:0x7c3588a0(92)] Hug:250 CompressionResistance:750>")

I know that the top and left and right and bottom constraints shouldn't log here because they are the superview constraints not the button constrains. But here I didn't add any width and height constrains to my button(even in code).

Why constraints height and width are logged in the console?

amin akbarzade
  • 227
  • 2
  • 13

2 Answers2

14

If a view has a natural width based on its content, it returns that width as intrinsicContentSize.width. Otherwise, it sets intrinsicContentSize.width to UIViewNoIntrinsicMetric.

Similarly, if it has a natural height, it returns that width as intrinsicContentSize.height. Otherwise, it sets intrinsicContentSize.height to UIViewNoIntrinsicMetric.

A button has a natural size (both width and height), determined by its title, font, image, and maybe other details. So its intrinsicContentSize.width and intrinsicContentSize.height are both valid sizes, not UIViewNoIntrinsicMetric.

When intrinsicContentSize.width != UIViewNoIntrinsicMetric, auto layout installs a special constraint of type NSContentSizeLayoutConstraint on the view. Similarly, when intrinsicContentSize.height != UIViewNoIntrinsicMetric, auto layout installs an NSContentSizeLayoutConstraint on the view.

For the details of what these special constraints do, see this answer.

Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • So you mean they are like real constraints? I forced my lable width grow, then I saw my button shrink. (because I didn't add constraint width to my button). If I add constraint width to my button (in interface builder) my button doesn't shrink. – amin akbarzade Apr 18 '16 at 07:16
  • Yes, they are real constraints, but by default they have a priority less than Required (1000). When you add your width constraint, it has a priority of Required (1000) by default, so it "wins". – rob mayoff Apr 18 '16 at 12:53
1

If view.translatesAutoresizingMaskIntoConstraints is FALSE then UIKit may add NSContentSizeLayoutConstraint to the view. In that case auto-layout uses -sizeThatFits: or intrinsicContentSize to compute the view's size.

If you have a view that you are moving from one superview to another, be sure to reset view.translatesAutoresizingMaskIntoConstraints. If the new superview uses auto-layout, set translatesAutoresizingMaskIntoConstraints to FALSE. If the new superview does not use auto-layout, set to TRUE. If you fail to reset translatesAutoresizingMaskIntoConstraints then you may see unexpected frame animations.