Using Auto Layout to distribute views uniformly in a superview - ios

I've laid out this view hierarchy in IB (Xcode 6.3.1):
I would like to use Auto Layout (FYI: I am new to Auto Layout) to distribute the subviews horizontally (their widths should always be equal to each other).
I'd really appreciate any pointers... the constraints I've added thus far have not kept the widths of the subviews equal.

You should add these constraints:
width of green == width of white
width of white == width of gray
leading space of green (to superview) == 8
horizontal space between green and white == 8
horizontal space between white and gray == 8
trailing space of gray (to superview) == 8
And you'll be good to go.
No need to specify that width of green == width of gray, they are already related to width of white, that'd be redundant, and autolayout hates redundancy.

Related

Creating grid with one big square using auto layout

Please advise on how should I approach implementing the following layout using Xcode's Auto Layout?
The idea here is that redView and all blueViews are all perfect squares with equal spacing.
I was only able to create working version with the redView and 2 vertical blueView without the bottom 3 blueViews.
Here is how I would approach it.
First create the big yellow square. Give it an aspect ratio of 1:1. Add a constraint to center it horizontally in the view. Give it leading edge and top edge constraints.
Add view B. Give it an aspect ratio of 1:1. Align it with the top edge and trailing edge of the yellow square.
Add view C. Align it to the trailing edge of yellow and center it vertically in yellow. Add equal width and equal constraints to view B. Give it a vertical space of 16 from view B.
Add view F. Align it to the trailing edge and bottom edge of yellow. Give it equal width and height of view C.
Add view E. Align it to the bottom edge of yellow. Center it horizontally in yellow. Give it equal width and height to F.
Add view D. Align it to the leading edge and bottom edge of yellow. Give it equal width and height to E.
Add view A. Give it aspect 1:1. Align it to leading edge of yellow and top edge of yellow. Align its bottom edge with bottom edge of C.
Change background color of yellow to clear.
That will do it. The yellow square will resize for all devices, and the red and blue squares will be sized accordingly. You can change the distance constraint between views B and C and all gaps will adjust automatically, which makes this easy to adjust for the desired look.
Here is an example running in the simulator. I hooked up the slider to change the value of the constant for the constraint setting the distance between views B and C.
See if this makes sense...
Embed all views in a "containing" view (it's yellow here, but the background color would be set to clear). This is the view that will control the overall size of your "grid."
Set the yellow width and height each to 320. As a starting point, this allows nice, even numbers: the Red view is 210x210 and the Blue views are each 100x100, with a 10pt gap between the views.
Put the Red view at x:0 y:0 - upper-left corner
Put Blue 1 at x:220 y:0 - upper-right corner
Put Blue 2 at x:220 y:110
Put Blue 3 at x:220 y:220
Put Blue 4 at x:110 y:220
And finally Blue 5 at x:0 y:220
The key to keeping the grid layout when the Yellow "containing view" changes size is to use a combination of Proportional Widths, Aspect Ratios and relative-to positions and sizes.
Red gets Top and Leading constraints of 0 to its superview (Yellow) - keeps it top-left-corner, an Aspect Ratio of 1:1 (keeps it square), and a Proportional Width to its superview (Yellow) of 210:320. That means if you change the Yellow view from 320x320 to 160x160, for example, the Red view will be constrained to 105x105.
Blue 1 gets Top and Trailing constraints of 0 to its superview (Yellow) - keeps it top-right-corner, an Aspect Ratio of 1:1 (keeps it square), and a Proportional Width to its superview (Yellow) of 100:320. That means if you change the Yellow view from 320x320 to 160x160, for example, Blue 1 will be constrained to 50x50.
That's it for the "tricky" constraints!
For Blue 2 thru 5, set each one to Equal Width and Equal Height to Blue 1.
Blue 2 gets Trailing of 0 to its superview (right-edge of Yellow), and Bottom equal-to Bottom of Red.
Blue 3 gets Trailing and Bottom of 0 to its superview (Yellow) - keeps it bottom-right-corner.
Blue 4 gets Bottom of Bottom of 0 to its superview (Yellow), and Trailing equal-to Trailing of Red.
Blue 5 gets Leading and Bottom of 0 to its superview (Yellow) - keeps it bottom-left-corner.
The Yellow containing view should have a 1:1 ratio to keep it square, then normal Position and Width constraints.
You can see the actual storyboard here: https://github.com/DonMag/ScratchPad (the Grid Of Boxes example)

iOS 8 Autolayout - Dynamically Resizing 4 Square Views

I have a view which contains a square subview (gray). This square subview then contains four smaller squares (blue):
Each of the squares are pinned to the top or bottom of the superview, and the left or right of the superview. For example, the top-left square has a constraint which pins the leading space to the superview and another constraint which pins the top space to the superview. Similarly, the bottom-right has constraints which pin the bottom and trailing spaces to the superview.
I am having real difficultly implementing constraints which will result in the squares resizing based upon the screen size. I have put horizontal and vertical spacing constraints between the squares, but that results in a warning that the content compression resistant priority on one of the squares needs to be reduced. When it's reduced, that square becomes tiny as the other square takes over all the space.
I just want each of the squares to be an equal size and resized by autolayout to fit the screen.
Any help would be appreciated!
Select all of the squares and apply Equal Widths and Equal Heights constraints to them all. Then, for one of the squares, apply an Aspect Ratio constraint to keep its width and height equal to each other. Finally, add a single space constraint between any two adjacent squares.
Those along with the constraints to pin each square to its corner of the superview should be enough.
Apart from the constraints in your image, I have added four space constraints with value 20 between adjacent squares, and align horizontal center of two squares on the right. You can refer to the below image.

Autolayout bottom spacing constraint is not obeyed

I have a UIButton and a UILabel constrained to be a standard distance from the bottom of the Superview. Works well on the iPad, but on the smaller iPhone screens, when other elements take up too much space, these views are pushed off the edge of the screen despite their constraint to remain a standard distance from the bottom. Why is this so?
What I would like to have happen is for the four rectangles to shrink in size so that there is still room for the "Go Back" and "Question" label to remain a standard distance from the bottom. The four rectangles can maintain aspect ratio and equal width/height by all shrinking at the same ratio. I have no constraints on their needing to be equal to or larger than a certain size. I've tried lowering their Content Compression Resistance Priority as well.
Configuration:
(I have also tried "equal" and "<=" in top spacing between "Go Back" & bottom left rectangle)
("Greater than or equal" works best on iPad to keep "Go Back" at the bottom of the screen)
How it looks on iPhone 6 and iPhone 6+ - with the labels cut off at bottom:
Did you try to lower those four buttons' height constraint's priority??
For example like this, try to set them to 750
You can make this work with a couple of changes and additions. Give the leading and trailing constraints between the top 2 rectangles and the superview a lower priority (I used 749), but still keep them as "equal". This will keep them at the standard distance from the edges if it's possible, but will allow them to have a larger spacing if the vertical space combined with the aspect ratio requires it. The problem with this, is that since they aren't required any more, when those constraints need to stretch, there's nothing that says they have to stretch equally; therefore, we need some way to keep the rectangles centered. So, instead of a spacing constraint between the left and right top rectangles, add a small view (I used 8x8) that has a centerY constraint to one of the rectangles, and zero constant spacing constraints to the two rectangles. Give this view a centerX constraint to the superview; this construct will give you the same spacing between your rectangles that you had before, but will keep them centered in the superview while allowing them to shrink in width (and height to keep the aspect ratio) if need to accommodate the vertical space.

Align multiple images equally in different screen size

I am having troubles aligning multiple images by using auto-layout in xcode.
I tried different settings, but nothing seems to work yet (refer to attached photos).
It would be great to hear some opinions from you guys, either in code or storyboard.
I want the image to be aligned equally in different screen sizes.
Too much space
Last image scaled too much
When Equally width is set
Constraints Setting
You need extra views to achieve this
In the sample picture the red rectangles they are all invisible UIView with constraints:
fixed length leading space to the view on the left(or the superview)
fixed length trailing space to the view on the right(or the superview)
fixed length height
This way it's the invisible views who have different width in different screen size while the size of images between them is fixed.
For left most item you should specify leading space to superview, for right most specify trailing space to superview. For all inner gaps between views specify horizontal spacing and for each neighbor view specify equal width constraint. Additionally I recommend for you to specify Align center Y for all views and set the y position constraint only for one of them

Make UIView Height Dependent On Negative Space Between Two Objects

I know how to do this in code, but I am desperately trying to get this to work via the interface builder.
I have a UIView's, and then 2 UIView's below it.
I have the top UIView and the Bottom UIView set with rigid constraints.
I want the middle UIView to resize based on the space between them. If you look at the image below you can see the white space. I would like to know what constraint(s) I could use so that the dark blue bar bases its height on the space between the upper and lower UIViews.
TL;DR How can I get the dark blue bar to have its height be the negative space between 2 views.
Thanks!
The dark blue bar should have the following constraints:
vertical space to white view = 0
vertical space to light blue view = 0
leading space to superview = 0
trailing space to superview = 0

Resources