How to trap on UIViewAlertForUnsatisfiableConstraints? How to trap on UIViewAlertForUnsatisfiableConstraints? ios ios

How to trap on UIViewAlertForUnsatisfiableConstraints?


This post helped me A LOT!

I added UIViewAlertForUnsatisfiableConstraints symbolic breakpoint with suggested action:

Obj-C project

po [[UIWindow keyWindow] _autolayoutTrace]

Symbolic breakpoint with custom action in Objective-C project

Swift project

expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]

Symbolic breakpoint with custom action

With this hint, the log became more detailed, and It was easier for me identify which view had the constraint broken.

UIWindow:0x7f88a8e4a4a0|   UILayoutContainerView:0x7f88a8f23b70|   |   UINavigationTransitionView:0x7f88a8ca1970|   |   |   UIViewControllerWrapperView:0x7f88a8f2aab0|   |   |   |   •UIView:0x7f88a8ca2880|   |   |   |   |   *UIView:0x7f88a8ca2a10|   |   |   |   |   |   *UIButton:0x7f88a8c98820'Archived'|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb0e30'Archived'|   |   |   |   |   |   *UIButton:0x7f88a8ca22d0'Download'|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb04e0'Download'|   |   |   |   |   |   *UIButton:0x7f88a8ca1580'Deleted'|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8caf100'Deleted'|   |   |   |   |   *UIView:0x7f88a8ca33e0|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca35b0|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca4090|   |   |   |   |   _UIPageViewControllerContentView:0x7f88a8f1a390|   |   |   |   |   |   _UIQueuingScrollView:0x7f88aa031c00|   |   |   |   |   |   |   UIView:0x7f88a8f38070|   |   |   |   |   |   |   UIView:0x7f88a8f381e0|   |   |   |   |   |   |   |   •UIView:0x7f88a8f39fa0, MISSING HOST CONSTRAINTS|   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8cb9bf0'Retrieve data'- AMBIGUOUS LAYOUT for UIButton:0x7f88a8cb9bf0'Retrieve data'.minX{id: 170}, UIButton:0x7f88a8cb9bf0'Retrieve data'.minY{id: 171}|   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8f3ad80- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8f3ad80.minX{id: 172}, UIImageView:0x7f88a8f3ad80.minY{id: 173}|   |   |   |   |   |   |   |   |   *App.RecordInfoView:0x7f88a8cbe530- AMBIGUOUS LAYOUT for App.RecordInfoView:0x7f88a8cbe530.minX{id: 174}, App.RecordInfoView:0x7f88a8cbe530.minY{id: 175}, App.RecordInfoView:0x7f88a8cbe530.Width{id: 176}, App.RecordInfoView:0x7f88a8cbe530.Height{id: 177}|   |   |   |   |   |   |   |   |   |   +UIView:0x7f88a8cc1d30- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1d30.minX{id: 178}, UIView:0x7f88a8cc1d30.minY{id: 179}, UIView:0x7f88a8cc1d30.Width{id: 180}, UIView:0x7f88a8cc1d30.Height{id: 181}|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc1ec0- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1ec0.minX{id: 153}, UIView:0x7f88a8cc1ec0.minY{id: 151}, UIView:0x7f88a8cc1ec0.Width{id: 154}, UIView:0x7f88a8cc1ec0.Height{id: 165}|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e68e10- AMBIGUOUS LAYOUT for UIView:0x7f88a8e68e10.minX{id: 155}, UIView:0x7f88a8e68e10.minY{id: 150}, UIView:0x7f88a8e68e10.Width{id: 156}|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e65de0- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e65de0.minX{id: 159}, UIImageView:0x7f88a8e65de0.minY{id: 182}|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e69080'8-6-2015'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8e69080'8-6-2015'.minX{id: 183}, UILabel:0x7f88a8e69080'8-6-2015'.minY{id: 184}, UILabel:0x7f88a8e69080'8-6-2015'.Width{id: 185}|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0690'16:34'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8cc0690'16:34'.minX{id: 186}, UILabel:0x7f88a8cc0690'16:34'.minY{id: 187}, UILabel:0x7f88a8cc0690'16:34'.Width{id: 188}, UILabel:0x7f88a8cc0690'16:34'.Height{id: 189}|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc2050- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc2050.minX{id: 161}, UIView:0x7f88a8cc2050.minY{id: 166}, UIView:0x7f88a8cc2050.Width{id: 163}|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e69d90- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e69d90.minX{id: 190}, UIImageView:0x7f88a8e69d90.minY{id: 191}, UIImageView:0x7f88a8e69d90.Width{id: 192}, UIImageView:0x7f88a8e69d90.Height{id: 193}|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cc00|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e618d0|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5ba10|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cd70|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e58e10|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5e7a0|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cee0|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dc70|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e64dd0|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e65290'Average flow rate'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e712d0'177.0 ml/s'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8c97150'1299.4'|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dde0|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3df50'Maximum flow rate'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbfdb0'371.6 ml/s'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0230'873.5'|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e2a0|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3e410'Total volume'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0f20'371.6 ml'|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e870|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3ea00'Time do max. flow'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0ac0'3.6 s'|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ee10|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3efa0'Flow time'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbf980'2.1 s'|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f3e0|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3f570'Voiding time'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc17e0'3.5 s'|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f9a0|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3fb30'Voiding delay'|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc1380'1.0 s'|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e65000|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52f20'Show'|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6e1d0|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52c90'Send'|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e61bb0|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e528e0'Delete'|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6b3f0|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ff60|   |   |   |   |   |   |   |   |   *UIActivityIndicatorView:0x7f88a8cba080|   |   |   |   |   |   |   |   |   |   UIImageView:0x7f88a8cba700|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3150|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3b10|   |   |   |   |   |   |   UIView:0x7f88a8f339c0|   |   UINavigationBar:0x7f88a8c96810|   |   |   _UINavigationBarBackground:0x7f88a8e45c00|   |   |   |   UIImageView:0x7f88a8e46410|   |   |   UINavigationItemView:0x7f88a8c97520'App'|   |   |   |   UILabel:0x7f88a8c97cc0'App'|   |   |   UINavigationButton:0x7f88a8e3e850|   |   |   |   UIImageView:0x7f88a8e445b0|   |   |   _UINavigationBarBackIndicatorView:0x7f88a8f2b530Legend:    * - is laid out with auto layout    + - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES    • - layout engine host

Then I paused execution Pause and I changed problematic view's background color with the command (replacing 0x7f88a8cc2050 with the memory address of your object of course)...

Obj-C

expr ((UIView *)0x7f88a8cc2050).backgroundColor = [UIColor redColor]

Swift 3.0

expr -l Swift -- import UIKitexpr -l Swift -- unsafeBitCast(0x7f88a8cc2050, to: UIView.self).backgroundColor = UIColor.red

... and the result It was awesome!

Hinted View

Simply amazing!Hope It helps.


You'll want to add a Symbolic Breakpoint. Apple provides an excellent guide on how to do this.

  1. Open the Breakpoint Navigator cmd+7 (cmd+8 in Xcode 9)
  2. Click the Add button in the lower left
  3. Select Add Symbolic Breakpoint...
  4. Where it says Symbol just type in UIViewAlertForUnsatisfiableConstraints

You can also treat it like any other breakpoint, turning it on and off, adding actions, or log messages.


Followed Stephen's advice and tried to debug the code and whoa! it worked. The answer lies in the debug message itself.

Will attempt to recover by breaking constraint NSLayoutConstraint:0x191f0920 H:[MPKnockoutButton:0x17a876b0]-(34)-[MPDetailSlider:0x17a8bc50](LTR)>

The line above tells you that the runtime worked by removing this constraint. May be you don't need Horizontal Spacing on your button (MPKnockoutButton). Once you clear this constraint, it won't complain at runtime & you would get the desired behaviour.