sonoluminescence
sonoluminescence

Reputation: 1012

How to find out the exact conflicts with NSLayoutConstraints?

I'm trying to position my 40x40 Logo on top of the screen, 20pt from the top, and lastly horizontally aligned with the parent view.

var views = ["tableView":self.tableView!,"logoImageView":logoImageView,"view":self.view]

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[logoImageView(40)]", options: nil, metrics: nil, views: views))

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[logoImageView(40)]", options: nil, metrics: nil, views: views))

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[logoImageView]", options: nil, metrics: nil, views: views))        

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[view][logoImageView]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views));

But this is the error I got in the debugger/console.

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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7fa78487e8f0 V:|-(20)-[UIImageView:0x7fa784b29350]   (Names: '|':UIView:0x7fa78373b8e0 )>",
    "<NSLayoutConstraint:0x7fa784886f70 V:[UIView:0x7fa78373b8e0]-(0)-[UIImageView:0x7fa784b29350]>",
    "<NSLayoutConstraint:0x7fa78488caa0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fa78373b8e0(667)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7fa784886f70 V:[UIView:0x7fa78373b8e0]-(0)-[UIImageView:0x7fa784b29350]>

Would be great if someone can help explain where's the issue and what's the proper way to do NSLayoutFormatOptions.

Thanks!

Upvotes: 1

Views: 397

Answers (2)

Ken Thomases
Ken Thomases

Reputation: 90571

The problem is with these two constraints:

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[logoImageView]", options: nil, metrics: nil, views: views))        
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[view][logoImageView]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: views));

The first says that the top of logoImageView should be 20 points from the top of its superview. The second says that the top of logoImageView should be 0 points from the bottom of view.

The problem is that view is the superview of logoImageView. You can tell because the superview (|) in this constraint:

"<NSLayoutConstraint:0x7fa78487e8f0 V:|-(20)-[UIImageView:0x7fa784b29350]   (Names: '|':UIView:0x7fa78373b8e0 )>",

is the same as the adjacent view in this constraint:

"<NSLayoutConstraint:0x7fa784886f70 V:[UIView:0x7fa78373b8e0]-(0)-[UIImageView:0x7fa784b29350]>",

So, the two constraints together require that view be 20 points tall. However, the table view is imposing a height of 667 points for that view, as shown with this constraint:

"<NSLayoutConstraint:0x7fa78488caa0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7fa78373b8e0(667)]>"

Hence the conflict.

I suspect the problem is that you have added logoImageView to the wrong view or you meant to list some other view in the V:[view][logoImageView] visual format string.

Upvotes: 2

Luca D&#39;Alberti
Luca D&#39;Alberti

Reputation: 4849

I discovered this simply way:

  1. When you notice the error log, press Pause to start the lldbdebug session
  2. In console type: expr [(UIImageView *)0x7fa784b29350 setHidden: YES];

You will notice that the view

<NSLayoutConstraint:0x7fa78487e8f0 V:|-(20)-[UIImageView:0x7fa784b29350]>

will disappear, and so you will know which it is

Upvotes: 0

Related Questions