iOS Autolayout: How to show / hide a view including its margins? - ios

Assume the following, simple layout:
Three views vertically stacked upon each other
Using simple vertical spacings between the views
Is it possible to hide the red view including its margins using constraints / AutoLayout only?
Settings redView.isHidden = true will hide the red view but will not change the position of the blue view. The blue view will stay at the same position as if the red view would be visible.
Using redView.removeFromSuperview() to completely remove the red view would show the desired result. Due to its optional spacing constraint to the gree view the blue view would move to where red view was. However it would be quite hard to re-show the red view because all its constraints would have to be set up from scratch.
In Android setting the visibility to View.INVISIBLE simply hides a view (as the first case described here) while View.GONE renders the remaining layout as if the view was not there at all.
Can this be done with iOS using constraints / AutoLayout only?
Of course I can achieve the same buy manually manipulating the constraints and setting up new constraints in code. But the question is, if there is a more convenient solution as in Android?

A VerticalStackView seems to fit your requirements. You can include all the views in the stack view and set the spacing directly on it.
Then, is one of the views is hidden, the stack view will automatically adjust all the constraints.
Take a look at the pictures:

If possible, wrap your views in a vertical UIStackView. You can then individual views and the other views will be rearranged as intended. You also don't need to add constraints between items, since the stackview handles the spacing between views.

The simplest way is to embed the views into a StackView and when one of them is hidden, the one below will move up into its place.
Follow these steps:
Add all the views you need in the storyboard/xib
Editor - Embed in stackView
Set the spacing in the stackView
Set the stackView constraints
Create outlets for the views you want to be hidden in a certain case
Set that views hidden property to true
Regarding the constraints, you can set them for the StackView and for the vertical one, just set the equal spacing and the space properties in the StackView.
Result:

Related

Adding Size Constraints for Views inside a UIStackView

I currently have a UIStackView that I add views to, it fits a maximum of 10 views along with a button. The issue however, is that although the views I add are equal size, the button is not.
I have tried adding a constraint that determines sets the button's equal to 1/11th of the StackViewSize (so that all of the views can fit equally), but it just seems to break all the other constraints.
How can I give the button size without breaking a million constraints?
Currently the height of the button is adjusted with each new view added, but that's just ugly.
First of all, set height and width to that button according to your requirement using AutoLayout. Then select your stack view from the Document Outline(in your view controllers hierarchy) & then in Attribute Inspector set its Distribution to 'Fill Proportionally'. Add some spacing if you want.

Is it possible to have overlapping views with auto layout?

I'm trying to have to views overlap as shown in the picture below, but I couldn't figure out how would I go about doing it with auto layout.
I tried doing the bottom view programmatically, and it worked fine except for the button which I had laid out using interface builder.
If it's possible to have views overlap what are the constraints needed, and is there a way to let the button show on top of the view in the bottom without doing programmatically?
You can do something like this.
make the second view uplift with minus value:
Here is the output. SecondView(green) has been uplifted to -50
You can do overlapping views using InterfaceBuilder. First create the top view i.e the one with image, give its constraints like top ,trailing,leading and bottom space. Then create the overlapping view.
The constraints for the overlapping view can be its trailing space, leading space,bottom space and height.
Then add those buttons inside that view.
In the interface builder, using a constraint, hook the top of the bottom view to the bottom of the top view, and then edit the constant in the Size Inspector to move it like you want.
It should look something like this:

How we can increase width of two button when we remove third button from view

I have view with three button with equal size. Each button take 1/3 part portion of view.
Like this image:
If I remove/hide one button then two button width should increase equally and take 1/2 portion of view. if I remove two button then one button size should be equal size of view.
My question is, how it's possible using the Autolayout.
Best option is using stackView. StackView gives lots of flexibility in adding or removing items. If you wish to use only auto layouts, you can achieve it by connect it's width constraints as IBOutlet and change the values programatically.
Best way to do that is to use UISTACKVIEW.Place a stackview and add 3 buttons.You can give proper layout constraints to the stack view as you need
click on stack view-- select attribute inspector
change distribution--fill equally
spacing--0
Then after that if you hide any button,other buttons will be automatically adjusted in width
Other Possible sol to this problem is Adding or removing constraints during runtime is a heavyweight operation that can affect performance. However, there is a simpler alternative.
For the view you wish to hide, set up a width constraint. Constrain the other views with a leading horizontal gap to that view.
To hide, update the .constant of the width constraint to 0.f. The other views will automatically move left to assume position. and for equal width pervoid multiplier to width..
You have a few options:
UIStackView which was made exactly for this.
UICollectionView similar to UIStackView in a certain way, but not really meant for this. However, it does the job nicely and it's easy to implement. Sometimes easier than UIStackView.
NSLayoutConstraint by using multiple constraints with different priority so that you can activate/deactivate them as needed and get the desired result. This approach is a bit more complex by it gives you the highest degree of control and flexibility over the views in your hierarchy.
The best way to achieve what you are looking for is, like others have already mentioned, to use a UIStackView.
When the isHidden property of a UIView inside a stack view is set to true, that stack view will hide the view and take care of the layout, so you will only need to set the correct constraints for your stack view.

AutoLayout : Relative scaling of views

I want to achieve consistent views across different screens. My layout constraints works on small screens perfectly but it scrambles on large screens.
I have made a view(Red Border indicating that view)and pin it in to the main super view. Then I have made sub views and put it inside that view. I have pinned the the top bottom trailing and leading edge of the layout which contains button of the it's parent view (Red Border indicating that view). The view containing button is looking like this in small screen (iPhone 5)
while it's looking in big screens like this (iPhone 6 and above)
I want this layout to have the same relative height in all the screens like the other views. How can I achieve this?
I guess you can use UIView that contains a button inside and set bottom,lead,trailing,top constraints for the UIView. Then you can set height constraint of that UIView and set multiplier values to have relative height to its superView(=Red box). Finally, you can set constraints for your button inside the UIView whatever you want. If you know how to use StackView, I recommend you to use it because it is easy and simple solution. Here is very good tutorial about StackView.
If height is constant for subview except that button view the layout will be like what you mentioned in the first image .If you kept height as constant for that button view the problem will be solved

Why auto layout constraints not working?

I'm setting constraints in IB like
But when i run the app on iPhone4 it shows
Why last three buttons not shown properly on iPhone4 screen?is there any mistake in my constraints ?
Edit:- This is my view hierarchy:-
UITabbarControlle -> UINavigationController -> UIViewController and tab bar controller is rootviewcontroller.
Edit:- FYI there is no effect of any constraints on the screen(basically autolayout not working for me).
You have designed the buttons on 4 inch and you don't have enough space on 3.5 for all of them.
One way to do this is to place scroll view over your view controller's view and add the buttons on the scroll view.You have to add constraint on the scroll view , to be fixed on each side (without width/height).
After that grab all the buttons and add constrains on each side and sizes , so they will be fixed
If you , on other hand, have enough space for all the buttons to fit in 3.5' without any top/bottom margins you can add the button in UIView (instead of scroll view). Place the buttons in the view and set fixed width/height on that view.Center the view and it will keep his size (with the buttons inside on both screen sizes)
There is an issue in your constraints, you have to update them.
You can do as is shown on the image bellow:
Once done, you will see, the Orange lines under your buttons turned to blue.
I wish that helps you!
Your view is probably within a UIScrollView which will extend your total contentheight. It is not related to the absolute height of your viewport.
However, what do you expect? Your 3 buttons would overlay to the next buttons, if your theoretical approach would work.
What you need to to do is to wire all buttons to each other and give the view a top and bottom constraint to the top and bottom layout. You probably need to adjust your view to be on full screen and not to extend to the bottom.
Hint: as long as something is 'yellow' you need to add further constraints.

Resources