Understanding multiplier in auto layout to use relative positioning
There are a couple ways to do this. In the simplest case, you've already almost got it: if you want the horizontal boundaries to be at 10% and 90%, then you need to specify both constraints with respect to the trailing edge of the superview -- so Subview.Trailing
locks to Superview.Trailing
with a multiplier of 0.9
, as you say, but then Subview.Leading
also locks to Superview.Trailing
, just with a multiplier of 0.1
:
(and similarly for top / bottom)
On the other hand, the case you mention at the end is a little more complicated: "specifying a label's top should lie 10% beneath another label's bottom." For that you probably won't be able to use fixed percentage insets like the previous case. Instead, you can create an invisible spacer view between them: add a constraint with Spacer.Height = 0.1 * Superview.Height
and then attach it between the two labels. (You can also handle the previous case with these spacer views, but for that case it isn't really necessary.)
In my opinion, "You can't have a negative multiplier I don't think, and I don't believe a value greater than 1 does anything when constant is 0" exposed your comprehending deviation.
The rule underneath the hood is just a linear equation:
FirstItem.Attribute1 = (SecondItem.Attribute2 * Multiplier) + Constant
All measured in points. As you see, multiplier(a property of NSLayoutConstraint) is not the multiplier of constant. Follow the equation, what you don't understand will be clear.
As to your specific example, @Archaeopterasa presented a great solution, another is shown below:
Based on the fact you know how to do bottom and trailing, I suppose you've done these two. Then add another two constraints, the effect will be what you want:
At last, if you want to specify a label's top lie 10% beneath another label's bottom, it seems that you cannot implement it without writing a line of code. You have to use code to set the constant of the NSLayoutConstraint object connecting the FirstItem and the SecondItem after the superview's height is known in runtime.
Firstly, control drag from one label to the other and choose "Vertical Spacing".(Or you can do this in other ways)
Secondly, a referencing outlet is needed:
@IBOutlet weak var tenPercentOfSuperview: NSLayoutConstraint!
Then, do this in a appropriate place(for example, in viewDidLoad())
let heightOfSuperview = self.view.bounds.heighttenPercentOfSuperview.constant = heightOfSuperview * 0.1
Everything is OK now.
If you want to know more about this topic, Apple's document is recommended:https://developer.apple.com/library/ios/recipes/xcode_help-IB_auto_layout/chapters/EditingConstraintAttributesintheAttributesInspector.html
Here's the
INCREDIBLY SIMPLE
way to do it.
Just add 'helper' or "measure' views:
The 'calculation helper' views are yellow in the example.
The general technique is so simple and obvious - it doesn't need any explantion, you can get it from the image.
It's one of those "elephant in the room" things they "don't teach you about" in iOS. But it is used constantly in all layouts.
(Indeed, Apple should have made a special UIView subclass "measures" for exactly this purpose - and indeed, many large teams do just that, with the obvious features.)
Notice icon #1 is centered on the right end of the "View 1/4" helper view.
Notice icon #3 is centered on the left end of the "View 3/4" helper view.
You're done, have a Chardonnay.
Conveniently, in the helper views, just set the multiplier to anything you want, depending on the feel wanted. It's incredibly easy to then change those in your code, use IBInspectable, animate, and so on and on...