I have some trouble with NSLayoutConstraint.
NSLayoutConstraint gives me an exception if I try to alter constant using the setConstant: method. I only have this problem when I add the height constraint via code.
First off, I’m getting the height constraint like so:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeWidth];
NSArray *filteredArray = [[self constraints] filteredArrayUsingPredicate:predicate];
return filteredArray[0];
Which gives me the right constraint. I have a NSTextField subclass where this works perfectly. The constraints are set in the Interface Builder, and I can set and alter the constant.
Now I have a view, where I add different subviews at run-time.
Those subviews are located in own NIBs, which means I can’t pin their width and height.
So I thought I’d add the constraints as soon as the view is being added to a superview.
This is being executed in viewDidMoveToSuperview.
// Pin Width & Height
[self addConstraint:[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:self.frame.size.width]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0f
constant:self.frame.size.height]];
The constraints are added, I can confirm this with an NSLog.
"<NSLayoutConstraint:0x100605cc0 H:[ITControlPanelChildView:0x100616eb0(269)]>",
"<NSLayoutConstraint:0x100614410 V:[ITControlPanelChildView:0x100616eb0(317)]>"
Now, finally, when I try to alter the constraint using [constraint setConstant:somethingDifferent]; I get the following exception:
Unable to simultaneously satisfy constraints:
(
"<NSLayoutConstraint:0x10192fcb0 V:[ITControlPanelChildView:0x10192e4f0(100)]>",
"<NSAutoresizingMaskLayoutConstraint:0x10053ff10 h=--& v=&-- V:[ITControlPanelChildView:0x10192e4f0(317)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x10192fcb0 V:[ITControlPanelChildView:0x10192e4f0(100)]>
This is exactly the constraint I’m trying to change.
Can anyone explain to me why this is happening?
EDIT
I just read that the NSAutoresizingMaskLayoutConstraints are added automatically, which you can disable if you set [self setTranslatesAutoresizingMaskIntoConstraints:NO];.
If I disable it, it works.
Even better would be if I could access the NSAutoresizingMaskLayoutConstraint which are created. Does anyone know how this works?
As indicated in the rest of the log message that you haven’t included, you’ve got autoresizing constraints that you don’t want or need.
You can remove these when you add the subview. In the method you’re using above, just add this line:
Though if you are creating the view in a separate nib, where is it getting its size from? Doesn’t it already have size constraints which you can just create outlets to?