iOS8 Auto layout programmatically pin to relative layout margin

倖福魔咒の 提交于 2019-11-30 02:40:30

问题


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?


回答1:


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];



回答2:


I agree, "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, You should tick the option “Constrains to margin” when you use Interface builder to assist your layout. If so, then it does work.

If problem was still not solved, could you give me a demo project?

Added: This article whcih show us the function of new ios8 API preservesSuperviewLayoutMargins, wish it be more helpful.



来源:https://stackoverflow.com/questions/26157077/ios8-auto-layout-programmatically-pin-to-relative-layout-margin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!