Creating a Percentage Based iOS Layout

Percentage based margin using autolayout

What you want is the left of sview to be at some point of the left of view and you are writing that you want the left of sview to be at some point of the width of view which is not a correct pairing of layout attributes as your error says.

Here is what you need to do:

NSLayoutConstraint(item: sview, 
attribute: NSLayoutAttribute.Left,
relatedBy: NSLayoutRelation.Equal,
toItem: view,
attribute: NSLayoutAttribute.Left,
multiplier: 1,
constant: (CGRectGetWidth(view.bounds) * 0.75));

Hope it helps!

EDIT

I found a great article about Percented based margins:
https://web.archive.org/web/20170624134422/http://simblestudios.com/blog/development/percentage-width-in-autolayout.html

Or even simpler:

https://web.archive.org/web/20170704113819/http://simblestudios.com/blog/development/easier-percentage-width-in-autolayout.html

Sample Image

How to create percentage of total width using autolayout?

If, as you say, you know how to do it in code, then you already know how to do it in the storyboard. It's exactly the same constraints, but you are creating them visually rather than in code.

  1. Select both a view and its superview.

  2. Choose Editor -> Pin -> Widths Equally to constrain the width to be equal to the superview's width (actually the "pin" popup dialog at the bottom of the canvas works best here).

  3. Edit the constraint and set the Multiplier to the desired fraction, e.g. 0.42. And so too for the other views.

Autolayout Percentage-based Placement in Right-to-left Language

Found the issue- it turns out the issue is that when the autolayout constraints flip direction, the coordinate system does not. This means that the standard LTR constraint is placing the trailing edge at 80% of the right edge's coordinate value (which is equal to the view's width). However, when the view constraint is flipped for the RTL language, it is now 80% of the left edge's coordinate value, which is now 0.

Unfortunately, there doesn't appear to be an easy solution to this. I tried placing the view at a percentage relative to the center of the view instead. Again, it works fine in LTR but when switching to RTL it maintains the exact same location on the right side of the view (so it does not mirror properly). TBH, I'm not sure how any percentage-based constraints work in both LTR and RTL that aren't centered.

The solution for now is to set the constraint at runtime based on the appropriate paradigm. So in LTR I set it at about 150% of the center coordinate, but if it's RTL I go about 50%.

Issue when percentage based layout (view equal height and width to Superview by multiplier ) for landscape mode

You mean like this?

Sample Image

I did that by using a UIStackView and switching its .axis between .horizontal and .vertical.

If this is iPhone-only, you can configure that change in Interface Builder:

Sample Image

But that won't work on iPad, since you have no size class change when we rotate; you would have to make the swap in code (in viewWillTransition).

How to set a constraint using percentage?

Update

Sorry, I have misunderstood your problem.

You'll need to add the constraints from code like so (the xConstraint is totally arbitrary, but you must need to define x, y positions, width and height, for an unambiguous layout):

@IBOutlet weak var imageView: UIImageView!

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

let yConstraint = NSLayoutConstraint(item: imageView, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1, constant: view.bounds.height / 3)

let xConstraint = NSLayoutConstraint(item: imageView, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1, constant: 30)

NSLayoutConstraint.activateConstraints([yConstraint, xConstraint])
}

This way, the equation will be:

imageView.top = 1 * view.top + (view.width / 3)

Original answer

Auto Layout uses the following equation for constraints:

aView.property = Multiplier * bView.property + Constant

Based on this, you can simply add an equal width/height constraint, then add a multiplier:

Sample Image

So the equation will be:

view.height = 0.3 * superView.height + 0


Related Topics



Leave a reply



Submit