StackView not appearing correct on all screen sizes - swift

I have a ViewController that contains a Stack View. In this Stack View there are 3 more Stack Views. The first contains 3 labels, the second contains more Stack Views with buttons and labels, and the third contains 2 buttons and a label. And at the bottom, there is a button. The layout is fine on screen sizes from 4,7" and bigger. But when the screen size is smaller, it cuts out the top Stack View. I have tried to set constraints on leading, trailing, top and bottom in different variations (with and without top and bottom constraints) But I can't make it work properly. I have attached screenshots of the different screen types.
EDIT* Depending on the selection from the previous ViewController, the middle Stack View(the one with the check boxes) can be isHidden When its hidden, the view is correct.

Generally you don't set height on UIStackView. They are dependent on it's content. This will cause your stackview to get out of the screen height. Have you used the view hierarchy? If you want to cover the small sized phones you could put your main stackView inside a scrollView to still be able to see all content.

It's a bit difficult to diagnose what's happening without seeing the constraints you apply to the views, however I'll recommend you some things that may help:
Set the space between views using size classes so you can set the right one depending on the screen size and avoid the overlap with the below views.
In case you are doing it, don't set a height constraint for any stackView.
To align the top StackView I would use not only a top constraint to the top bar (of type greater than or equal) but also a vertical center constraint with a right multiplier (with a high priority). In this way you ensure the top stack view is aligned vertically in proportion to the screen size and with the top constraint you ensure the stackView doesn't hide below the top bar.
Make sure you are hiding the right stackView.

Related

How to constraint elements in view?

IMPORTANT: This is not a main view but a view I added on the main one and it has its size.
I'm trying to constraint this view in order to make it resizable on every iOS device. I want it to look exactly how you see it.
I followed multiple guides online but even if I do exactly what I see it doesn't seem to work for me.
Here's what I tried:
I set the cancel's button width, then I constrained it to the view (trailing, bottom, leading) and vertically in container. I did the same for the one above it but the bottom constraint was attached to the button.
As regards the view with a lot of square buttons I:
Constrained the view to the button below it (bottom), set its width, placed it vertically in container, top space to safe area (I have a navigation bar above my view) and trailing and leading space to view.
As regards the buttons inside my view I set equal widths and hights for each of them and then I constrained them all top leading trailing and bottom (they all have a space of 7 between them or their view).
None of this works since the blue sky view either becomes bigger and wider, either goes outside of the screen, either everything gets very weird... How could I do?
I think this question is a bit tricky to answer. But I'll try my best :D
So, the first thing I would do is to put the pink squares inside a stackView and let autolayout help us a little. Then I would constrain the blueSkyView.top .leading and .trailing. After constrain the stackView .top, .leading, .trailing, .bottom to the blueSkyView, so that blue sky view could enlarge to fit the stack inside.
Then constrain the buttons to the bottom, just like you made. Consider using some constraints of Greater than from blue sky to Random Color button, for example, guaranteeing they will never overlap.
If you want to make this view a square for very time while using different devices, you need to give a height constraint for the view and also a leading and trailing.
Then make an outlet for the height constraint. In the viewDidAppear method you should wright the below code:
heightConstraint.constant = myView.frame.size.width

How to set constraints to multiple UIImageView's in Swift

After hours of attempting to find a solution, as well as trying and failing myself I decided to ask here.
As shown on the picture below I have 15 Image views in a pyramid shape that I would like to set constraints on.
I have tried to:
Constraint equal width and height on all images
Constraint center image on line 1, 3 and 5 to horizontal center
Align vertical centers to all images on each line
Etc etc
The result is always the image view going out of bounds or similar issues. (Clip to Bounds is true)
Anyone have a solution or suggestions?
try putting them all in stack views then putting all those stack views inside a stack view and putting constraints on that
like this take a look at the view hierarchy on the left
to get the spacing i achieved just adjust the spacing on the right inside the attributes inspector
and its even able to have constraints on the highest stack view
all the errors go away once you add constraints to the top stack view
like shown here
Embed all your imageViews in a UIView.
set the top, bottom, leading and trailing constraint inside that view (top image to the superview, etc.).
align the UIView horizontally and vertically in the container.
You probably also want to set a width to your UIView, but I let you think about the final result you want.

How to preserve constraints for hidden views within UIStackView

I have three buttons within a horizontal stack view and I have set the autolayout up so they appear based on certain criteria.
For example, first button will be 40% of the stack view width, second button has the same width as the first button, and third button takes the remaining width. Height of the buttons are the same as the stack view. They are all spaced equally, 8 points apart. Stack view's distribution is set to to "equal spacing" and alignment is set to "center".
The issue appears when I decide to hide the first two buttons, but still would like the third button to appear in the same spot with the same width. Autolayout would resize the third button as if the first button and second button are not there.
How do I make it so the autolayout created continues to be preserved as if the hidden buttons are still there?
Couldn't you just set the alpha to 0 and userInteractionEnabled to NO for the buttons you want to "hide"? This would cause them to disappear, and I don't think that it will cause the third button to expand.
Use a second constraint to the container that can act as a backup constraint. Or just re-recreate the desired constraint via code.
I have one more better solution. Add the three UIView in stack align as per your need, then add the button in every UIView. Now you can play with button hidden true/false, here UIView will always be with clear color. Alignment won't change.

UIScrollView Causing "Misplaced Views" AutoLayout issues

I'm running into a strange AutoLayout related issue when I use a UIScrollView (the issue does not occur without it).
I have a UIScrollView that is constrained to the boundaries of a UIView (contained within a UIViewController), and within that, I am attempting to place a UILabel and UITextField side by side. I have constrained the UILabel to the left and upper boundaries, with it's width and height constrained (see screenshot below):
Right next to this UILabel is a UITextField, which is constrained to the left, top, and right, as well as having the height constrained. However, this results in a "Misplaced Views" warning, that states "Expected width = 163, Actual width = 413", shown in the screenshot below:
When I choose to "Reset to Suggested Constraints", the "Misplaced Views" issue disappears, but in it's place I am left with a width constraint of 413 points, which is something I'm hoping to avoid, as I would not like this UIViewController to be horizontally scrollable on smaller devices.
A scroll view has a size (the size it takes up on the screen) and a content size (the size of the entire scrollable area). In Auto Layout, the content size is automatically computed from the constraints of the items in the scroll view. This is a problem, because you are trying to make the scroll view have the same width as your screen, and then have the items constrained to that. When you do that, Auto Layout insists that you give your text field an explicit width so that it can calculate the width of your scrollable area.
To do what you want, do the following:
Add a "content view" to your scroll view. This view will be the only top level item in your scroll view. It will hold all of your content as subviews of it. Drag out a UIView and add it to your scroll view. Constrain its top, leading, bottom, and trailing edges to the scroll view. Constrain its width to the width of the scroll view. Give it a height constraint and set it however big you want your content area to be.
Add all of your labels and textfields to this content view. Now you can constrain them centered in your content view or constrained to the edges, and it will work as you want.

Changing which view stretches when using auto layout and pinning

I am updating my app to handle the iPhone 5 layout. I have a view that has a variety of components.
I am using auto layout and almost have everything setup correctly. My challenge is that I have pinned two views so that they have a vertical spacing of 0. This makes sure that one of the views stretches so that the items stay touching. However, I want the view that is currently stretching to stay in place, and for the other view to stretch and meet at the edges. Does this make any sense? Anyone have any experience with this?
if you want to fix the height of a view put a constraints with the height of the view and the other view will be fixed by bottome end the vertical spacing will be 0 betwwen those views.