How to find the crashing constraint? - xcode

Sometimes I keep getting errors like these - without any hint to which TextView or Button is meant:
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:0x11d748d0 V:[UITextView:0xc1bb000(65)]>",
"<NSLayoutConstraint:0x11d77620 V:[UIButton:0x11d71cf0(44)]>",
"<NSLayoutConstraint:0x11d7be30 V:[UIButton:0x11d79e70(43)]>",
"<NSLayoutConstraint:0xa1980d0 V:|-(134)-[UITextView:0xc1bb000] (Names: '|':UIView:0xa1afba0 )>",
"<NSLayoutConstraint:0xa199ed0 UITextView:0xc1bb000.centerY == UIButton:0x11d71cf0.centerY>",
"<NSLayoutConstraint:0xa199e50 V:[UIButton:0x11d79e70]-(61)-[UIButton:0x11d71cf0]>",
"<NSLayoutConstraint:0xa199cb0 V:|-(40)-[UIButton:0x11d79e70] (Names: '|':UIView:0xa1afba0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x11d748d0 V:[UITextView:0xc1bb000(65)]>
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Is there a way to identify the constraint in the code that is causing the crash?
The text:
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x11d748d0 V:[UITextView:0xc1bb000(65)]>
unfortunately doesn't help much, since I do not have any idea which constraint this is in code

You read them like this:
<NSLayoutConstraint:0x11d748d0 V: [UITextView:0xc1bb000(65)]>
^ Constraint type ^ Address ^Axis ^Description in VFL
(of constraint)
So this is a constraint forcing the textview to be 65 points high. In there you also have a constraint pinning this text view to 134 points from its superview's top edge:
<NSLayoutConstraint:0xa1980d0 V:|-(134)-[UITextView:0xc1bb000] (Names: '|':UIView:0xa1afba0 )>
And a constraint pinning the Y center of the text view to the Y center of a button:
<NSLayoutConstraint:0xa199ed0 UITextView:0xc1bb000.centerY == UIButton:0x11d71cf0.centerY>
And a constraint pinning the button itself to a specific vertical location:
<NSLayoutConstraint:0xa199e50 V:[UIButton:0x11d79e70]-(61)-[UIButton:0x11d71cf0]>
It is likely that you didn't want all these constraints. Here you have two constraints that are trying to position the text view vertically (based from the button, and based on absolute spacing from the top of the superview).
Somewhere in your app you must have a view with a text field and two buttons. If you break on all exceptions you can log out the various addresses given in the log and find out the superviews and so on if you're not sure, but hopefully you'll be able to work it out from this.
Sometimes it is helpful to copy the log into a text editor and find / replace the addresses with words so that it is easier to read.

Related

Xcode 9 - Labels overlapping on iPhone SE Screen size

I don't know what constraint I need to add to prevent the labels from overlapping on a smaller screen size. I've tried placing a horizontal constraint between the two labels, however on larger screen sizes, the symbol label doesn't stay at the end of the view.
These are the constraints I've made for the two labels.
https://i.imgur.com/cicPYBR.png - Constraint 1
https://i.imgur.com/cicPYBR.png - Constraint 2
This is what it looks like on iPhone SE.
https://i.imgur.com/yxE9ce7.png
Easy Way
Use Stackview and add both of your view
With Constraints
To your left label (Where I can ..) add
Leading , Top , Bottom , Trailing (>= Relation) (with right side view which has play icon)
To your ride side view (which has play icon) add
Top, Bottom, Trailing (= relation ) (with super view) , Width (Whatever your constant with >= Relation )
In your first label you can set number of lines 2 and line break mode to word wrap to encounter ... in small devices
Hope it is helpful

Find a constraint using the hex code

I have some issues with auto layout, where the console says there are conflicting constraints. However, when Xcode attempts to fix the issue, everything works as intended. In the console it reports
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fe578db22f0 V:[UILabel:0x7fe578d9b200'Label'(32)]>
I want to find the constraint mentioned: "0x7fe578db22f0" and delete it manually.
Is there anyway to find it by using that hex code? And if not, can anyone suggest a way to fix my issue? I have a lot of constraints and it would be very difficult to go through and test each one.
If the question is merely how to identify which view that constraint is associated with, the easiest way is probably using the view debugger. So, run the app and click on the "debug view hierarchy" button. Then examine your view hierarchy in the left panel (narrowing it down by searching for view type, if you want), until you see a constraint that looks like the one in question. And by choosing the object inspector, you can confirm the address of the constraint in question.
Now that you've identified the precise constraint and view in question, the tracking down of its creation in the app should be much easier.
Add UIViewAlertForUnsatisfiableConstraints symbolic breakpoint help you debug autolayout easier !

Xcode 6 constraints on different sizes

I'm doing an iPhone app using Xcode 6
My problem here is, I add a constraint to an image, and all is fine, and than I try to add another constraint on a smaller screen and I get the error on the bottom of this message.
Is there any way of adding different constraints according to the size we are at? That is what it feels like on Xcode on the wAny hAny area, but for some reason it just doesn't work.
2014-10-06 17:41:45.059 testapp[2623:26567] 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) (
"",
"",
"",
"" )
Will attempt to recover by breaking constraint
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints
to catch this in the debugger. The methods in the
UIConstraintBasedLayoutDebugging category on UIView listed in
may also be helpful.
When a constraint receives a negative value or the value that contradicts with other values, it spits an error. For instance:
You have an image, that has height 500 and the constraint attached to it's bottom
You modify this constraint such a way that the image gets smaller and smaller (constant value)
Eventually image will have negative value, which is impossible. And the rest of the constraints will also "suffer"
Make sure that the height of the parent view is greater than the height of the image. Hopefully the example above will make you better understand the issue in general.

How do I (easily) delete a constraint in Interface Builder in Xcode 6

Assume you've selected an object and you have the Size Selector in the Utilities panel open. You can see the list of constraints applied to the object. In the list of constraints you could click on the little gear and pick delete. You can't in Xcode 6.
There are still several ways to delete constraints in IB:
Find the constraint in the Document Outline and delete it that way (but it can be hard to find).
Click on the little bar in the storyboard and delete it that way (which can be hard to click on).
Double click on the constraint in the Size Selector which will open Attribute Inspector and highlight the constraint in the Document Outline. This can be a nuisance when you want to delete several.
Still, I miss ease of use of the gear delete feature and I'm wondering if it's still there in a similar fashion and I just can find it. While the other ways work, I find myself wasting lots of time especially when playing with the new Size Classes feature. So, find a easier way to delete them?
In Xcode6 (Beta5) when I click on a particular constraint in the Size inspector, it acquires a thin blue border. The constraint can then be deleted using the backspace.
The accepted answer is right, but there is so much frustration with selecting constraints that lay outside of selected view that I decided to add this tips as another answer.
I found incredible list of tips that helped me to solve this problem.
The problem:
You select the view and Xcode shows related constraints.
You try to choose the one that is outside of selected view.
You fail (end with selecting the view beneath the constraint)
Soulution:
Click it with Shift+Ctrl pressed and you'll see a menu of all the views that exist where you've clicked.
To delete selected constraint press delete key.
The selected answer is incomplete. When you delete the constraint from the Size Inspector, you are leaving behind the constraint object in the Document Outline pane. It is greyed out, meaning it is not used, but still exists and, what's worse, will affect auto layout with errors, warnings or conflicting constraints and you will go crazy until you also delete them from the Document Outline pane.
So:
1. Delete the constraint from the Size Inspector as in the accepted answer
2. Delete any greyed out constraints from the Document Outline
Live a happy, constraint-free life.
This answer from #wayne chi is the simplest, and spares you from hunting down constraints in Document Outline:
Double click the grayed out constraint (switches focus to the constraint) then press delete. This will delete the constraint.
Sometimes, the easiest way is to close the file in Xcode and edit it with a text editor. :-/
If you want to delete ALL constraints from a viewController simply turn off auto layout and then reenable it (or don't) and all of the constraints will be gone.

Cocoa Autolayout - Why can't I delete or modify the (purple) width constraint on a Text Field?

I'm building a simple application using autolayout, and I've run into a strange situation. I place a Text Field in an empty part of a large open view so it's not affected by anything but the super view, but when I try to modify the "Width" constraint to be >= instead of ==, it creates a new constraint and refuses to modify the old one. I can't delete it, or change any of its attributes, because it just creates a new one.
Here is a comparison of the two constraints, the purple one being the stubborn one, and the blue one being the newly created one.
Why is the purple rounded one not modifiable?
I have worked around the presence of undeletable-but-unwanted constraints in IB by setting their priority to 1. Doesn't seem like the Right Thing to do, but sometimes I'm not smart enough to be a Cocoa developer.
My problem had to do with with fact that there weren't enough other constraints added that the width would ever be forced to change. When I added more other constraints (such as leading and trailing space), I was then able to alter the purple constraint (in fact, it disappeared and I had to add my own).
It seems strange that you cannot add your own constraints unless there is a possibility of them being broken, but I guess that's the way it's been integrated into IB in some cases.
Lowering the priority of the purple constraints will also make them editable.
I had a similar scenario, where there were two multiline labels. Based on the content size, both should resize.
When the first label resized, it was overwriting the second label because the second one had a Vertical Space constraint( "Top Space to SuperView = 40". it's a system default constraint - purple colour) which I was not able to delete/modify.
If I tried to modify it as "Top Space to SuperView >= 40", it'd be changed to a user constraint( blue colour) and a new purple constraint "Top Space to SuperView = 40" would be created automatically.
I guess this could be the reason:
When I tried to change the constraint to "Top Space to SuperView >= 40", the label's default position is undefined : >= doesn't specify a default position. It specifies only a 'range of positions'. Then I added a new constraint by selecting both the labels together and setting the space between them as a constant.
Now, since the first label had a definite position (vertical space = 15) from the top border and the second label was 5 points below the first one, the second label got a vertical position defined. I was able to delete the purple vertical space constraint.
Now, if I remove the constraint between the two labels, the second one will no more have the defined position and system will automatically create a purple constraint for the label.
When you right-click on the constraint, select "Promote to user constraint". Next time you click on constraint, you will be able to delete it as now it is in the hands of the user/developer.

Resources