Make UIView Height Dependent On Negative Space Between Two Objects - ios

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

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)

Using Auto Layout to distribute views uniformly in a superview

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.

How to specify a constraint for a UILabel to remain centered beneath each segment of a UISegmentedControl?

In my app for iOS 8, I have a UISegmentedControl that stretches to fit the width of the device's screen. So on an iPad it's more pixels wide than it is on an iPhone 6+, which is more pixels wide than the iPhone 6, etc.
Centered just beneath each segment of the UISegmentedControl, I have a UILabel. So there are 5 segments and 5 UILabels. Each UILabel has a fixed width (fixed by constraint). However if the display size increases they become uncentered.
How in Interface Builder can I specify a constraint that will force each UILabel to become centered beneath each segment? I would be happy if I could just get the elements to remain proportionally spaced with each other as the display size scales, but I can't figure out how to do that, either.
All I can seemingly do is to center the middle UILabel directly under the middle segment by specifying a Center X Alignment between that and the UISegmentedControl.
I specified a Horizontal Space constraint between all the UILabels, and between the outer UILabels and the edges of the view, and set all these to "greater than or equals". They all have the same priority, but strangely, they don't all scale proportionally to each other.
The resulting problem is that the amount of Horizontal Space between each of the UILabels does not scale smoothly as the width of the device's screen increases. If I align everything to be in the proper positions on the iPhone 5S width of screen, then on the iPad their alignment is all wonky, and only the middle one lines up with its segment. The rest of them are all off center.
It appears that there is no way to specify a percentage of the over-all display width as a constraint -- you can only specify things in terms of pixels. Really?!?!
Clearly I could make the width of the objects to be flexible, but because they are text labels with right-aligned text, that screws everything up.
Surely I'm missing something here... since the point of Auto Layout is to make your interface scale according to the screen size, surely there is a way to specify a constraint as a percentage of any given view or subview... surely!!! But how? I've read the documentation and I cannot, for the life of me, figure it out.
BTW I did see that in the past, people have used crude hacks like spacer views or multiple sets of constraints, but surely those are outdated answers, and I'm just overlooking something extraordinarily obvious... right?
You can do this by making the centerX constraint of your labels equal to the superview.trailing times 0.1, 0.3, 0.5, 0.7, and 0.9 with constants of 0. To make these constraints, add your 5 labels to the view. Give the left most one a vertical spacing constraint to the segmented control. Select all 5 labels and give give them a "vertical centers" alignment constraint. Now control-drag from each label to the right side of the screen, and select the "Trailing space to container margin" constraint. Edit each one of these trailing constraints to look like this (except for the multiplier that needs to be given the values I mentioned above):
You'll have to reverse the first and second item (which you do from the pull down on the first item), change the Label.trailing to Label.Center X, and uncheck the "relative to margin" box, then correct the constant and multiplier values.
This approach will only work if the segmented control stretches all the way across the screen with no padding to the edges. If you want padding to the edges, then you need to use a completely different approach. You would need to create 5 UIViews below your segmented control -- align the left edge of the left-most one to the left edge of the segmented control. Align the right edge of the right-most one to the right edge of the segmented control. Give the 5 views equal width, and 0 length horizontal spacing constraint from each to its neighbor. This will give you 5 views that mimic the segmented control in width, with each view being the same width as one of the segments (assuming all the segments are the same width -- if that's not the case, you're screwed). Then you only need to add your labels as subviews of these 5 views, and give them centerX and centerY constraints.

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.

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

Resources