How do you right align a horizontal UIStackView? - swift

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.

Related

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"

How to add subviews in stackview top to bottom?

I'm adding labels to a stackview and I'm having trouble getting them to add to the top of the stackview rather than the middle.
I'm trying to accomplish this with the following code:
let textLabel = UILabel()
textLabel.textColor = .white
textLabel.widthAnchor.constraint(equalToConstant: self.stkCombatStackView.frame.width).isActive = true
textLabel.text = "This is a test"
textLabel.textAlignment = .left
stackview.addArrangedSubview(textLabel)
I want the labels to be added from top to bottom, how can I do this? without the weird spacing?
I have the spacing in the inspector set to 1
(I also have the stackview nested in a scrollview in the storyboard but i can't seem to scroll the stackview at all)
I'm adding labels to a stackview and I'm having trouble getting them to add to the top of the stackview rather than the middle.
You should probably call insertArrangedSubview(_: at:) instead of addArrangedSubview(). The insert... method lets you specify the index at which to insert the new view.
I want the labels to be added from top to bottom, how can I do this? without the weird spacing?
Are you sure you're using the right tool for the job? A stack view is good for containing a heterogeneous list of views in a fixed space, and it moves and/or resizes the views in the list to fill the view evenly. Take a look at the Distribution values: you can either fill up the stack view by resizing the contents in a couple different ways, or you can spread the contents evenly across the height (or width) of the stack view. There's no option for just listing the contained views and leaving extra space at the bottom, which seems to be what you want.
Some options you could consider:
use a UICollectionView: Collection views are incredibly flexible, letting you lay out a list of items in any conceivable geometry; the provided layout manager will surely work for your needs, but if you don't like it you can write a layout manager of your own or use someone else's. UICollectionView is a subclass of UIScrollView, so scrolling is easy.
use a UITableView: A table view gives you a vertical list of (usually, but not necessarily, similar) cells that can contain anything you want, and that top to bottom behavior that you're looking for is inherent in the way a table works. UITableView is also a UIScrollView subclass.
roll your own: It's not that hard to create a view that simply contains a list of other views and lays them out according to any algorithm you like; if a table or collection won't work for your needs (which seems unlikely), writing your own container will work better than trying to force UIStackView into submission.

Left aligned horizontal stackview and top aligned vertical stackview

I have two StackView, one of which is horizontal and another vertical.
For the horizontal StackView, I want the items to be aligned to the left and grow toward the right.
For the vertical StackView, I want the items to be aligned to the top and grow downward. For example the position of the top item would never change but the stackview expands down if another item is added.
I'm having trouble accomplishing this, for example with my horizontal StackView, if I have two items 40x40, they will example the entire width of screen for some reason and I've tried a whole slew of different variations of distribution, alignment and constraints.
For my vertical StackView, if I add two items, my first item will move up and the second item will go underneath, so the center is now between the two instead of the first item staying still and the second going underneath it.
I can't figure out what I'm doing wrong here and how to just get StackViews where the first item is sized correctly, in place, and future items follow it, expanding either rightwards or downwards.
What you need is for Vertical
1- Drag a UIStackView with top , leading and trailing constraints to the superView
2- Drag any view inside it and give it a height constraint
for Horizontal
1- Drag a UIStackView with top , leading and height constraints to the superView
2- Drag any view inside it and give it a width constraint
Note : Make distribution set to fill

Auto Layout issues

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.

Container view getting truncated despite constraints in place

The scene has a container view inside of a superview, and I've constrained it with respect to the boundaries and 2 text boxes. Instead of "Numeric Value Please", I only see Nu... appearing on there. The console does not give me any constraint related warnings, and I don't understand why the blue view is able to fit in, but the controller is not.
Here are Alert Controller's constraints: http://i.stack.imgur.com/2xhZh.png. It's just constrained to the center.
Another picture of main view's constraints: http://i.stack.imgur.com/2qARq.png
The constraint to the right is too large (125), pushing the right edge of the container to the left.
You should just have: constraint from top (superview), constraint to left (the text field), height (optional), and slightly higher compression resistance. To prevent the text from going off to the right you can also have a >= constraint to the right (superview).
To break the text into two lines, set number of lines to 2 and choose "Word Wrap" + make sure you have a right side constraint and you are not constraining the height (too much).
Another remark: do you really need a "container" view? Why not just a plain UIView? Or does the label have its own controller? That seems like a somewhat convoluted design I think.