UPDATE: If you are in a Storyboard rather than a XIB file, you might want to use this easier method.
Today I needed to create a square, centered
UIImageView that was 50% of the width of its superview no matter it’s size for the launch image of our upcoming app Stabby.
I also wanted to do this using autolayout. Only using Interface Builder.
After some initial confusion, it turns out to be fairly easy!
Create a single view app or any other app, actually, as we will be using the
LaunchScreen.xib file that comes along with new projects in XCode 6.
Once the project opens, select the
LaunchScreen.xib file in the Navigator to start working on it. It will have a couple labels by default; trash them.
Add A Thing
Drag in a
UIView in roughly the middle of the parent view. This will be the view we work with. While it’s selected, use the Attributes Inspector to change the color to something other than white so we can see it. I have selected a boring grey. You make a better choice!
Make it square
While it’s still selected, use the Size Inspector to enter a height and width that will make it square. The values themselves aren’t important (I used 200 if you want to copy me) as long as the view has the aspect ratio you want. You can also drag it to the center of the superview, but it’s not needed, as it’s position and size will be changed by the constraints we add later.
Lock in the squareness
Ctrl-Drag on the square view we’ve added, and drag ever-so slightly so you are dragging the connection to itself (really!) and pick
Aspect Ratio. This ensures that when one side resizes, the other does as well. You’ll see some new constraints around your view with
1:1 to tell you just that.
Define your percentage based margins
For this example, I want to make my view 50% of the width of the superview. That gives me margins of 25% on either side if my art-school math skills are correct. You need to figure out the space on either side, rather than how wide you want the actual view to be, since we can’t specify width as a percent (at least to my knowledge, but I’d love to be wrong!)
Pin the left edge…
To make this work, we need to pin the edges “incorrectly” then edit the constraints later to get what we want. So start by pinning the left edge of the square view to the superview by Ctrl-Dragging from the subview to the left into the superview and picking
Leading Space to Container. You could also use the
Pin menu down in the bottom left of the editing area to do this. This gives us a constraint that sets a fixed value in points for the distance between the left edge of the superview and our subview.
…and edit the constraint
Select the constraint by clicking on it directly or by picking it from the list of stuff over on the side. We’ll be using the Attributes Inspector to change it to suit our needs. First, change the Second Item to
Superview.Center X. This switches the edge we pin to from the left of the superview to it’s center. Now we change the
Multiplier values to give us a percentage based margin. By default, you’ll get a
Constant value in points based on wherever your subview happens to be sitting. We are going to change this to
0 so we start off pinned directly to the center, so change whatever value is in the
Constant field to zero. Make sure you hit Enter when you change values in the Atrributes Inspector! Sometimes they don’t see to “take” for constraints for some reason unless you do.
By doing that, we have told autolayout “position the left edge of my subview equal to 50% of the width of the super”. This gives us our proportional edge, but in the wrong place. We want our left edge to be at 25% of the width of the superview, and that’s where the multiplier comes in. We do some basic math and see that multiplying the stock .5 (50%) by .5 gives us the .25 (25%) we are after. So set the
Multiplier value to
.5 (remember to hit enter), and have faith that it will work after all the other constraints are in!
Do it again, but backwards!
Lets take care of our right edge now. Once again, Ctrl-Drag from your subview into the superview, this time to the right, and pick
Trailing Space to Container. This give us a fixed size margin we can now edit. Select the new constraint, but before we start tweaking, notice that the
First Item and
Second Item are swapped from our other constraint. For a fixed size, this would be fine, but for our proportional one they need to be flipped. Doing this is as easy as picking
Reverse First and Second Item from either items drop down menu. Once you’ve done that, select
Superview.Center.X for the second item, and enter
0 in the
Constant field like we did before.
Multiplier value will be different, as we want the right edge to be on the other side of center. Putting our basic math skills to the test, we want this edge to be at .75 (75%) of the width of the parent, so from our starting point of .5, we need a multiplier of
1.5 to get us there. Add that in, and we are almost done!
We now have a horizontal position and size. All that’s left is a vertical position, and autolayout will have enough info to put our view where it needs to be. To keep you from having to read much more, we will simply fix the vertical margin to whatever value it happens to be. Ctrl-Drag from the subview up to the superview and pick
Top Space To Container. This will give us a fixed margin, and now all is well.
To see our fluid sizing in action, select the subview and from the triangle looking autolayout menu, pick
Update Frames if you need to. You should see everything turn blue to signify autolayout is happy, and you can now resize your superview in the editor and see the square view stay centered with proportional margins on the sides.
Thanks for reading, and until next time, happy coding! I would love to hear feedback or answer any questions via twitter: @veddermatic or by email
back to top