Friendtam
Friendtam

Reputation: 331

NSLayoutconstraint breakage since xcode 6.3

I am trying to set the below constraint to one of my floating view.

    leftConstraint = [NSLayoutConstraint constraintWithItem:detailView 
attribute:NSLayoutAttributeLeft
relatedBy:NSLayoutRelationEqual toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:0.0 
constant:VIEW_WIDTH];

The view will be moved horizontally and has a fixed width. I couldn't pin this view to any other view. I will be changing the constant value in the constraint to move it over my view.

When I run the above the constraint in XCode 6.3, am getting the below error. "A multiplier of 0 or a nil second item together with a location for the first attribute creates an illegal constraint of a location equal to a constant"

I am not sure why this creates an illegal constraint.

To bypass this issue, I am using the 0.001 multiplier, but thats not going to work in all cases. So looking for an better workaround to this requirement.

Upvotes: 3

Views: 3146

Answers (2)

DanielS
DanielS

Reputation: 181

If you'd like to position view to the left and add width constraint you have to use two constraints:

CGFloat leftConstraintConstant = 40.0f;
CGFloat VIEW_WIDTH = 200.0f;

NSLayoutConstraint *leftConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:detailView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:leftConstraintConstant];
NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:detailView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:VIEW_WIDTH];

[self.view addSubview:detailView];
[self.view addConstraints:@[leftConstraint,widthConstraint]];

To properly position your view you should also add separate constraint for Y-axis position and height. Please note that I haven't tested this code but it should give you brief understanding of what needs to be done.

Upvotes: 0

Matthias Bauch
Matthias Bauch

Reputation: 90117

This is the formula Autolayout uses:

item1.attribute1 = multiplier × item2.attribute2 + constant

So if you set multiplier to 0 or don't have an item2, attribute1 will be constant. Which is not a good idea because it's a constraint regarding to the superview without mentioning the superview. And in most cases it's the result of a bug in code. So Apple decided that it's illegal to create this kind of constraints.

Constraints without a second item are invalid for all attributes except height and width.

You should actually add your constraint explicitly in regards to the superview of the view.

Your constraint should look like this

leftConstraint = [NSLayoutConstraint constraintWithItem:detailView
                    attribute:  NSLayoutAttributeLeft
                    relatedBy:  NSLayoutRelationEqual
                    toItem:     detailView.superview
                    attribute:  NSLayoutAttributeLeft 
                    multiplier: 1 
                    constant:   VIEW_WIDTH];

Upvotes: 4

Related Questions