I have an UI element (UISwitch
actually, but does not matter really) that has both leading and trailing space pinned to superview in Interface Builder. The constraint looks like this in Xcode 6:
The constraint for leading space is the same effectively. The value of constraint is 42.0 points.
This is exactly what I want, because for different devices I can change layoutMargins
property on UIView
and the constraints will work correctly, to increase margin between views.
Now I want to add another view in code that would also have both leading and trailing space pinned to it's superview margin, so the same layoutMargins
set to superview will work.
I pinned the view using visual format language with the following syntax:
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-42.0-[separatorView]-42.0-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(self.contentView, separatorView)];
[self.contentView addConstraints:constraints];
[self.contentView setNeedsUpdateConstraints];
This works, but layoutMargins
property has no effect using this constraint, so it is obviously not pinned to margin, but directly to superview.
So my question is:
How to pin UI element spaces to margin in code using visual format language? Or if not possible, how to pin with constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:
API?
In iOS8, the visual format language has been updated so that "|-" or "-|" will default to using a spacing defined by the superview's layoutMargins property.
So the answer using visual format language is as follows:
// programmatically set the layoutMargins, only if
// you want non-default values and they are not already set in IB!
self.contentView.layoutMargins = UIEdgeInsetsMake(0,42,0,42); // set left and right margins to 42
// assume: seperatorView is already a subview of self.contentView
// separatorView will use the constraints because we write "-" between it and the superview edge
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-[separatorView]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(separatorView)];
[self.contentView addConstraints:constraints];
If you want to refer to the layout margins when creating the constraints via the direct API, then you use the new iOS8 only layout attributes:
NSMutableArray * constraints = [NSMutableArray array];
[constraints addObject:[NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeLeftMargin
relatedBy:NSLayoutRelationEqual
toItem:separatorView
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:0]];
[constraints addObject:[NSLayoutConstraint constraintWithItem:self.contentView
attribute:NSLayoutAttributeRightMargin
relatedBy:NSLayoutRelationEqual
toItem:separatorView
attribute:NSLayoutAttributeRight
multiplier:1.0
constant:0]];
[self.contentView addConstraints:constraints];