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)
Related
actually I'm trying to fit my app for all the size of screen phones, I have a view (the blue square) which contains 2 rectangles at top and bot and 4 squares in the 4 angles of the view and I'm struggling how to make my view (and the contains) have a dynamic resizing on different phone as you can see for the iPhone 4 it takes all the screen... Thanks for the help.
my AutoLayout image
Looks like you set a fixed width constraint (with a constant of 334) to your blue square view. The smaller iPhones (4s and SE) have a screen width of 320pt, so your blue square view is too wide for them.
You have to make the blue square view's width dynamic (depending on the available screen width)
To achieve that you can set the blue square view's width constraint the be the same as its superview (the light blue view) and then define a multiplier. For example to define the blue square view's width to be 80% of the available width, you set the multiplier to 0.8
Here are the steps to set the dynamic width:
Delete the fixed width constraint
Select the blue square view and the light blue view
Add a new Equal Widthsconstraint
Select the constraint
In the Attributes Inspector define the Multiplier
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.
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.
I am having some problems dealing with constraints with squares. I need the squares (UIImageView) to be proportional for each iPhone size. I also need the words to stay proportional. I have tried a couple of different things but the squares seem to grow or shrink every time and go all over the place. Any Ideas?
Assuming you want to keep 8 circles in each diagonal line, and want them anchored to the corners of the screen:
Select all of the circles and select Editor > Pin > Widths Equally. And then do Heights Equally.
Select one of the circles and Control-drag from it to itself, and create an Aspect Ratio constraint. Make sure its multiplier is 1:1.
For all of the circles in a diagonal, create Horizontal Spacing constraints with 0 constant from one to the next. Same for the other diagonal. Then, the same for Vertical Spacing.
For the top-left circle of the top diagonal, pin it to the container's top and leading edge.
For the bottom-right circle of the top diagonal, pin its trailing edge to the container's trailing edge.
For the bottom-right circle of the bottom diagonal, pin it to the container's bottom and trailing edge.
For the top-left circle of the bottom diagonal, pin its leading edge to the container's leading edge.
That should get the circles to line up and size themselves proportional to the device's width.
For the "Color" label, pin its top and bottom to the blue circle to its right. Pin its trailing edge to the blue circle's leading edge with some spacing.
For the "Catch" label, pin its top and bottom to the green circle to its left. Pin its leading edge to the green circle's trailing edge with some spacing.
You probably want to also create constraints for the label edges on the far side of the circle to the corresponding edge of the container, with spacing and greater-than-or-equal-to relation, to make sure they don't extend off the edge.
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