When should we use UIStackView? - ios

I am designing iOS Application since 2 years. I have designed 8-10 applications with using UIScrollView, UICollectionView and many more native views. But I have never used UIStackView. I have gone through many documents of UIStackView, but I am not able to identify exact situation where i can use UIStackView.
Can anyone guide me for same?
Thank you in advance.

UIStackView is useful when you need to repeat same views multiple times like in Sing up view. We use many textfields and manually set constraints between each textfields. But if you put all textfields in stack view then you just need to set required constraints of stackview only and not textfields. Textfields inside stackview will be arranged automatically without Autolayout.
Sometimes we need to hide view and we want to remove its occupied space so at that time use of stackview is recommended because if you hide any view that resided in stackview will also remove its occupied space automatically.

I believe you mean UIStackView. You use a UIStackView to group UI elements together to simplify setting constraints. In other words once you've added objects to the stack view, you constrain the stackview and set attributes on it rather than on each individual element. This results in far fewer constraints.
In this example, I've added a label and a text field to a stack view. Then I added constraints to the stack view and set the spacing in Attributes Inspector to 20.
If I had to constrain the label and the text field I'd have many more constraints.

UIStackView helps you to set autolayout. It isn't neccessary!

Related

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

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:

UIStackView losing constraints when using custom XIBs

I am attempting to dynamically add views to a UIStackView.
I have a XIB with a full screen UIStackView within. I then have some views - labels and text field/ text views.
The idea here is that I have a class that manages these individual views and that class has it's own XIB file for the layout.
So the class that handles the outermost UIStackView will grab the layout from the individual classes and add it as a subview to the UIStackView.
When attempting to do this, the view appears squashed and not in keeping with the original constraints.
I could offer code but I will explain the constraints.
The outer UIStackView is just stretched as full screen with distribution fill and equal spacing.
An example of an 'inner' view would be a label. I have an individual XIB file that holds a UIView and then a Label within that. The label is pinned to the center of the UIView.
I believe the issue lies with adding custom XIBs to an existing UIStackView. I'm not sure how much more information I give/ is required but I suspect there is something I am missing that someone may spot straight away from the information given.
Any help is appreciated. Thanks.
The UIStackView does exactly what you are asking it to do. If the constraints are setup so the UIStackView fills in the entire screen, then you need to provide content, that when it is equally divided on the screen, has the expected layout, each of the view inserted will be resized to be equally sized.
If you do not know how many views are going to be used, but you need each of your views to take their respective aspect ratio on the screen, then you can use the "Fill Proportionally" option. The UIStackView will add the height of every view, then divide its own height and distribute it proportionally to each view. If you add too many views this too will start to squash your views.
To avoid these kinds of issues, you may wish to put your UIStackView inside of a UIScrollView. You then setup a constraint with very very low priority to set the UIStackView height to 0, as you insert your views the UIStackView will automatically be resized to fit in the different views.
Good luck!

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.

UIStackView without distribution or filling

I have a view on my app where I need to be able to push a dynamic number of custom subviews (the number of views changes whilst its running).
My original idea was a tableview, but it seems a bit OTT setting up all the delegate methods. Then i found UIStackView, which is great as it handles redrawing and resizing when I add and remove the subviews.
However when I have a small number of views in the UIStackView. It will either make each view bigger vertically to fill the space, or distribute them across the stackview depending on the various settings.
What i'd like to have is each view I add just be appended under any existing views in the stack. I don't want distribution or filling of the blank space in the stack. Kind of like a UIStackView with each subview having a height constraint.
I assume this isn't possible with a stackview, so how else can this be achieved? Do I have to use the tableview after all (or fallback to laying it out in code?)
If your views have a defined height constraint, this should work with the Distribution being Equal Spacing.
I managed to do this by setting distribution to fill proportionally and then i pushed at the bottom of the stack a UILabel with some spaces as string. Pushing an empty view or empty UILabel didn't work. I had some constraints errors after this though and didn't investigate further.

Override spacing for a UIStackView

I frequently find that a UIStackView is perfect for a particular layout, except that I need some variable spacing between the arranged subviews. UIStackView uses its spacing property to arrange the views along its axis, but is there a way to override these? For example, I would love to be able to add a single manual constraint using the visual format to define the required gaps, and somehow de-prioritize those of the stack view.
I could forgo the UIStackView entirely of course, but the stack's ability to give back space between hidden subviews is pretty painful to replicate manually (adding and removing constraints based on which views are hidden, for example). I also tried wrapping individual subviews in their own stack views so that I can use the stack's layoutMargins to add a top-margin. But this then requires managing the wrapper-stack's own hidden state in addition to that of the subview it contains (surprisingly - to me - a UIStackView whose arrangedSubviews are all hidden is not automatically hidden itself, so does not yield its spacing and margins back to its own superview).
From iOS 11 it is possible to use:
stackView.setCustomSpacing(spacing: CGFloat, after: UIView)

Resources