eliamyro
eliamyro

Reputation: 308

Button heightConstraint breaks autolayout

Below is the UI of one of my controllers.

controllerUI enter image description here

As you can see at the bottom of the screen (in portrait) I have two UIButtons with an image. Those two buttons are placed inside a horizontal UIStackView with a .fillEqually distribution. The buttons have a heightConstraint in order to keep a correct aspectRatio. The heightConstraint is:

leftButton.heightAnchor.constraint(equalTo: leftButton.widthAnchor, multiplier: 0.75)
rightButton.heightAnchor.constraint(equalTo: rightButton.widthAnchor, multiplier: 0.75)

When the device is in portrait and gets rotated to landscape everything works fine, but when the device gets rotated again to portrait I get the following stack trace:

2018-10-12 12:08:16.643313+0300 Music for Kids[5823:114100] [LayoutConstraints] Unable to simultaneously satisfy constraints.
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. 
(
   "<NSLayoutConstraint:0x600003e996d0 UIStackView:0x7f96a6e338a0.top == UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide'.top   (active)>",
"<NSLayoutConstraint:0x600003e99720 UIStackView:0x7f96a6e338a0.leading == UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide'.leading   (active)>",
"<NSLayoutConstraint:0x600003e99770 UIStackView:0x7f96a6e338a0.bottom == UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide'.bottom   (active)>",
"<NSLayoutConstraint:0x600003e997c0 UIStackView:0x7f96a6e338a0.trailing == UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide'.trailing   (active)>",
"<NSLayoutConstraint:0x600003e999f0 H:|-(0)-[UIView:0x7f96a6e33c80]   (active, names: '|':UIView:0x7f96a6e062c0 )>",
"<NSLayoutConstraint:0x600003e99a90 UIView:0x7f96a6e33c80.trailing == UIView:0x7f96a6e062c0.trailing   (active)>",
"<NSLayoutConstraint:0x600003e9a0d0 UIButton:0x7f96a6e1f320.height == 0.75*UIButton:0x7f96a6e1f320.width   (active)>",
"<NSLayoutConstraint:0x600003e9a170 UIImageView:0x7f96a6e348a0.width == 0.95*UIView:0x7f96a6e33c80.width   (active)>",
"<NSLayoutConstraint:0x600003e9c8c0 'UISV-alignment' UIView:0x7f96a6e062c0.bottom == UIStackView:0x7f96a6e336a0.bottom   (active)>",
"<NSLayoutConstraint:0x600003e9e9e0 'UISV-alignment' UIView:0x7f96a6e062c0.top == UIStackView:0x7f96a6e336a0.top   (active)>",
"<NSLayoutConstraint:0x600003eb77a0 'UISV-canvas-connection' UIStackView:0x7f96a6e336a0.top == UIButton:0x7f96a6e1f320.top   (active)>",
"<NSLayoutConstraint:0x600003eb5270 'UISV-canvas-connection' V:[UIButton:0x7f96a6e2d200]-(0)-|   (active, names: '|':UIStackView:0x7f96a6e336a0 )>",
"<NSLayoutConstraint:0x600003eb3660 'UISV-canvas-connection' UIStackView:0x7f96a6e336a0.leading == UIButton:0x7f96a6e1f320.leading   (active)>",
"<NSLayoutConstraint:0x600003eb3610 'UISV-canvas-connection' H:[UIButton:0x7f96a6e1f320]-(0)-|   (active, names: '|':UIStackView:0x7f96a6e336a0 )>",
"<NSLayoutConstraint:0x600003e80640 'UISV-canvas-connection' UIStackView:0x7f96a6e338a0.leading == UIView:0x7f96a6e062c0.leading   (active)>",
"<NSLayoutConstraint:0x600003e881e0 'UISV-canvas-connection' H:[UIStackView:0x7f96a6e336a0]-(0)-|   (active, names: '|':UIStackView:0x7f96a6e338a0 )>",
"<NSLayoutConstraint:0x600003e9caa0 'UISV-canvas-connection' UIStackView:0x7f96a6e338a0.top == UIView:0x7f96a6e062c0.top   (active)>",
"<NSLayoutConstraint:0x600003e9cd70 'UISV-canvas-connection' V:[UIView:0x7f96a6e062c0]-(0)-|   (active, names: '|':UIStackView:0x7f96a6e338a0 )>",
"<NSLayoutConstraint:0x600003eac910 'UISV-fill-equally' UIButton:0x7f96a6e2d200.height == UIButton:0x7f96a6e1f320.height   (active)>",
"<NSLayoutConstraint:0x600003eb31b0 'UISV-spacing' H:[UIView:0x7f96a6e062c0]-(8)-[UIStackView:0x7f96a6e336a0]   (active)>",
"<NSLayoutConstraint:0x600003eb4460 'UISV-spacing' V:[UIButton:0x7f96a6e1f320]-(8)-[UIButton:0x7f96a6e2d200]   (active)>",
"<NSLayoutConstraint:0x600003eb67b0 'UIView-Encapsulated-Layout-Height' UIView:0x7f96a6e2dd90.height == 812   (active)>",
"<NSLayoutConstraint:0x600003eb4b40 'UIView-Encapsulated-Layout-Width' UIView:0x7f96a6e2dd90.width == 375   (active)>",
"<NSLayoutConstraint:0x600003e99590 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide']-(34)-|   (active, names: '|':UIView:0x7f96a6e2dd90 )>",
"<NSLayoutConstraint:0x600003e99540 'UIViewSafeAreaLayoutGuide-left' H:|-(0)-[UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide'](LTR)   (active, names: '|':UIView:0x7f96a6e2dd90 )>",
"<NSLayoutConstraint:0x600003e995e0 'UIViewSafeAreaLayoutGuide-right' H:[UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide']-(0)-|(LTR)   (active, names: '|':UIView:0x7f96a6e2dd90 )>",
"<NSLayoutConstraint:0x600003e994f0 'UIViewSafeAreaLayoutGuide-top' V:|-(88)-[UILayoutGuide:0x6000024ca760'UIViewSafeAreaLayoutGuide']   (active, names: '|':UIView:0x7f96a6e2dd90 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600003e9a0d0 UIButton:0x7f96a6e1f320.height == 0.75*UIButton:0x7f96a6e1f320.width   (active)> 

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

From what I understand the heightConstraint of the buttons causes this error! If I don't put a heightConstraint I don't get an error but I need itinerary order to keep a correct aspectRatio.

Do you have any ideas?

Upvotes: 1

Views: 907

Answers (1)

HAK
HAK

Reputation: 2081

Your aspect ratio constraint tells that more width, more height. When in portrait, width of each button is smaller as compared to the width when in landscape.

Now since there is more width when in landscape the layout system tries to increase the height as well. But in landscape, you don't have enough room to expand to the desired height. This breaks the height constraint.

I think you can fix it by lowering the priority of the height constraint so that when there is not enough space to increase the height, it will stop without generating horrible log.

Upvotes: 2

Related Questions