Auto Layout issues - swift

I am trying to get a layout working where I have 9 squares set 3 x 3 and on all device sizes, they are square.
I have tried endless ideas to make it work but can't seem to get it to stay squares on all devices.
I attached below, a picture showing the results and current constraints on the top left corner square.
Any help would be awesome!

The best approach would be use the stackView. The advantage will be you do not have to deal with the much constraints. So select the first rows three view horizontally then click on the Embed in Stack button whose axis should be horizontal inside your storyboard. Follow the same for second and third rows. Also inside stackview you can mention the spacing you want.
So now you have three stackView for all the three rows. After that select all three stackView then click on the Embed in Stack button and whose axis should be vertical and you can mention the spacing you want.
So advantage of doing that is you do not have to worry about the constraints. Finally you only have to apply the constraint on your main stackView which hold all your child stackView

While I totally agree that UIStackView is a great option, you can also add Aspect Ratio constraints (with a Multiplier of 1) to your squares and ensure that they remain squared (as nothing about your current layout demands that your views should be squares).
If you want your 9 squares to remain in the center of the superview, I recommend adding them to an invisible intermediate view and center that within the superview.

Related

Aspect ratio constraint is not working for UIStackview with nested UIstackviews

I have a view controller with six buttons.
I want to show them in 3 rows and 2 columns.
I decided to put each column of buttons (3 buttons) in a stack view and put 2 vertical stack views in 1 horizontal stack view.
I want my buttons to look square shaped.
I applied following constraints for the horizontal (main) stack view:
Align Center X to Safe Area
Align Center Y to Safe Area
Align leading to Safe Area Equals:50
Aspect Width:Aspect Height = 2:3
For some reason aspect ratio is not working and the width is still
larger than the height and more importantly the buttons are not square shaped.
I tried to update frames, to apply all possible alignment and distribution properties, however, it didn't solve the problem. Please check images below for your reference.
View Controller
Constraints
Thanks in advance!

Autolayout: always gaps between views in the stack view, despite setting constraints to theTopView.bottom = theBottomView.top

I'm new to Swift and trying to repeat the calculator app as part of the learning, but got stuck at the autolayout.
Here's what I did:
Set each row as a Horizontal stack view, and all rows together as a Vertical stack view.
Set the vertical stack view Distribution as Fill Equally.
Set constraints for each Horizontal stack view as theTopView.bottom = theBottomView.top, and vice versa.
Set constraints of each element inside each Horizontal stack view as element.Top = stakcView.Top, element.Bottom = stakcView.Bottom.
Gap with distance set at 0:
However, there are always gaps between the Horizontal stack views, despite showing the distance between them being 0.
Can someone tell me what I did wrong? Why are there gaps despite showing 0 as the distance between these two? Your help is really appreciated!
constraints:
A UIStackView arranges its subviews. Don't try to add positioning constraints between the arranged subviews - that counters what you've told the stack view to do.
You need to decide how you really want your buttons to look.
In this case:
The 0 label is not contained in any stack view.
I gave the % button an aspect ratio of 1:0.75.
The "outer" Vertical stack view and the Horizontal stack views are all set to Fill Equally.
Here are the constraints - the only difference between the 3 layouts is:
1-> Left image has the "outer" stack view centered vertically - no Top or Bottom constraint.
2-> Center image has the "outer" stack view Bottom constrained to the view Bottom (of safe area).
3-> Right image has the "outer" stack view TOP constrained to the Bottom of the "0" label.
If you want the buttons to fill the screen:
Remove the Aspect Ratio constraint from the % button.
Outer stack view has Top constrained to label Bottom, and Bottom constrained to view Bottom (safe area)
Thanks for your answers!
While they are all informative, fundamentally, my problem lies somewhere else: there are always mysterious gaps between stack views regardless what the constraint constant is set to.
For example, it was set to 0
Space between stackviews when set to 0
Then it was set to 20000
Space between stackviews when set to 20000
Then I discover that it was the space setting was accidentally set to larger than 1. When I set it to 1 the mysterious gap went away.
enter image description here
Problem solved. Thanks again for your help!
Try "Fill" instead of "Fill Equally"

What is wrong with these auto layout constraints?

What I aim:
I want to have a table cell, in which every cell is horizontally divided in two halves. The upper half will contain 4 labels, and the lower half will contain 4 values which correspond to these labels.
Of these 4 items in every horizontal half, each of the last 3 items will occuppy 2/7 of total width, and the remaining 1 item will occupy the remaining of the total width, which is 1/7 of total width.
What I tried:
Putting a horizontal stack view in the content view of table cell.
Which will contain two vertical stack views
Where the upper vertical stack view will contain the labels and the lower vertical stack view will contain the values.
In short, I did this:
But I am getting these conflicts:
I really don't understand why I am getting these conflicts. I feel like I have provided enough constraints for auto layout to do the layout correctly.
Could you please tell me what is wrong here?
I'm on Xcode 8 and using iPhone 7 Plus as view, if that would make any difference.
This is a simpler case, and it isn't working as well:
Conflicts:
As you have provided the detail nobody can get understand and help to resolve your auto-layout issues, I suggest you to clear all constraints and try re-apply all the constraints again , give proper leading and trailing with x and y position the constraints will definitely works good,
Once you will try to apply twice or thrice you ll get know the exact problem and it will be get resolved quickly.
For auto-layout more practice needed to understand it briefly.
Hope it will help to you,
Thanks.

How do you right align a horizontal UIStackView?

I've yet to find an answer for this anywhere and I'm not sure if it's possible, but I'm trying to right align a horizontal UIStackView, so that if subviews are hidden they move towards the right side not the left. Either programmatically (in Swift) or using the Interface Builder
UIStackViews align according to the user's text direction, i.e. left aligned for English and other Roman script languages, or right aligned for languages such as Hebrew.
In my opinion, changing this for layout reasons may be a misuse of the text direction APIs, and a bit of a hack, but with that in mind:
You can change the direction for a particular view in interface builder, using the Semantic drop down, which has options for 'Force Left-to-Right' and 'Force Right-to-Left', which will change the direction they pop to but also the order they are shown in. So you will have to reverse the order of the elements in your stack view
Or you can do it in code, using the view's semanticContentAttribute
stackView.semanticContentAttribute = .forceRightToLeft
What worked best for me was putting my horizontal stackview inside a vertical stackview and set the vertical one's alignment to leading
Unlike the other answers, the solution is actually fairly simple. What you need is to add a trailing constraint that pins the stack view to the trailing edge of its superview and then also add a leading constraint that pins it to the leading edge of the superview.
The trick, however, is changing the leading stackview constraint relation from equal to greater than or equal.
That will allow the leading edge of the stack view to snap over to the intrinsic width of the contents of the stackview, effectively pinning everything to the trailing edge.
Vertical stack views are similar. Pin the top with equals, and pin the bottom with less than or equal.
So:
stackView.leadingAnchor.constraint(greaterThanOrEqualTo: parent.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: parent.trailingAnchor).isActive = true
stackView.distribution = .equalSpacing
I had a horizontally oriented UIStackView containing two UIViews; hiding one of the views led to the other spreading full-width. Adding a width constraint to the remaining view resulted in keeping the desired width, but it shifted to the right.
TL;DR
Add a hidden UIView to the stack view which shows when the other is hidden for spacing.

How to adjust multiple rows of labels in Xcode so that they occupy around 70 % of screen height?

I'm trying to build an app that has just a single portrait oriented view. There is a title on top and results label at the bottom of the view, these are locked to top and bottom and center, no problem here.
Now this is the tricky part. I have 9 rows of labels, most single row but couple span out to 2 rows. I want them to spread out evenly between the title and the result-label.
I lock the first label to top-left, lock the leading edges and then set equal vertical distance constraints between the labels. Otherwise ok but the last labels on 3.5 inch display overrun my results -label.
So I adjust either the fontsize or make vertical distance between labels smaller or both. 3.5 inch problem fixed but now there is a big empty gap between the last label and result. On iPhone 6 its really ugly.
I have tried all sorts of methods but can't just get this working.
So basically: how do I reserve 10 % of view height from top and 20 % from bottom and tell Xcode to use the rest 70 % (and all of it) for my 9 rows of label, evenly?
Thanks for help!
Would have posted an image but no rank for such things...
If I understand you right, you need several flexible spaces that will all be the same size. One space in-between each of the labels.
Create UIViews to put between each label, set them all to have equal widths or heights and anchor each one to the views it is supposed to sit between.
I got this idea from another SO question: Springs in Auto Layout: Distribute views evenly, with constraints, in Xcode 5