18

I'm trying to align the items in UIStackview horizontally to the left.

Is there anyway to do this programmatically? I tried to do this via storyboard but was not successful. For some reason, the items in the UIStackView centers itself.

Hamer
  • 1,354
  • 1
  • 21
  • 34
Yong Jia Pao
  • 181
  • 1
  • 1
  • 3
  • I hope [this answer](http://stackoverflow.com/a/40256540/5501940) to useful to you. You need apply the same approach but horizontally instead of vertically. – Ahmad F Dec 28 '16 at 19:49

8 Answers8

28

If you use StackView setting axis property to "Horizontal", I think you can't align it to the left.

But there is a way to make it left visually.

  1. set StackView leading constraint with "equal" relationship
  2. set StackView trailing constraint with "greater than or equal"

like this

stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(greaterThanOrEqualTo: view.trailingAnchor).isActive = true
shtnkgm
  • 1,396
  • 15
  • 17
  • 1
    This worked for me to get items to align left with desired spacing between items. – Augie May 13 '18 at 20:50
  • 2
    Great solution! If you're working with storyboard and constraints, you will have some issues. Just put a placeholder that you remove at runtime to hide this issue. – Tom Jul 26 '18 at 16:13
  • 3
    Perhaps I am missing something but if we want to align elements to the left it should be lessThanOrEqual – OhadM Oct 03 '21 at 13:13
14

Try Adding One Space View in Your Stack View , Like this

 // To Make Our Buttons aligned to left We have added one spacer view
    UIButton *spacerButton = [[UIButton alloc] init];
    [spacerButton setContentHuggingPriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
    [spacerButton setContentCompressionResistancePriority:UILayoutPriorityFittingSizeLevel forAxis:UILayoutConstraintAxisHorizontal];
    [self.buttonsStackView addArrangedSubview:spacerButton];

And Make

self.buttonsStackView.distribution = UIStackViewDistributionFill;
Ankit Maurya
  • 762
  • 8
  • 11
8

Swift 4.2 + iOS 12.1 tested:

    let stackView: UIStackView = UIStackView(frame: .zero)
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.axis = .vertical
    stackView.alignment = .leading // <- aligns each of your items to the left. 

    // further setup + setup constraints
    // ...
Baran
  • 2,710
  • 1
  • 23
  • 23
  • 1
    stackView.translatesAutoresizingMaskIntoConstraints = false this one helped to have clean log without uisv-spacing warnings about broken constraints – Serj Rubens May 07 '19 at 13:47
  • Is `leading` alignment is not available when setting in storyboard? – Hemang Dec 04 '19 at 19:44
  • 1
    @Hemang I can answer your question. I'm only building my views in code. But you could do the following. Create your stack view via storyboard and link it to your code and configure the stack view in code rather in the storyboard. – Baran Dec 05 '19 at 13:59
  • 1
    Thanks @BaranEmre for the tip. – Hemang Dec 06 '19 at 07:50
  • 4
    .leading works only with .vertical, but the question is about horizontal – beryllium Oct 19 '20 at 16:04
7

Thanks to @Ankit Maurya, solution with example for swift

 let stackView = UIStackView()
 stackView.axis = .horizontal
 stackView.distribution = .fill
 
 let spacer = UIView()
 spacer.isUserInteractionEnabled = false
 spacer.setContentHuggingPriority(.fittingSizeLevel, for: .horizontal)
 spacer.setContentCompressionResistancePriority(.fittingSizeLevel, for: .horizontal)

 // stackView.addArrangedSubview.... any u need
 stackView.addArrangedSubview(spacer)

Example:

enter image description here

hbk
  • 10,908
  • 11
  • 91
  • 124
2

Use the UIStackView.alignment property.

Reference: https://developer.apple.com/reference/uikit/uistackview/1616243-alignment

crizzis
  • 9,978
  • 2
  • 28
  • 47
0

Thanks for the advice guys. I tried playing with the options on UIStackView.alignment but it never really worked as desired. In the end I messed with the width of the UIStackView to achieve the desired results.

if(prdDTO.getShellIcn() == "Y")
    {
        let icon = UIImageView()
        icon.contentMode = UIViewContentMode.scaleAspectFit
        icon.image = #imageLiteral(resourceName: "Shellfish")
        prdIngredients.addArrangedSubview(icon)
        stackviewWidth += 25
    }

    if(prdDTO.getVegeIcn() == "Y")
    {
        let icon = UIImageView()
        icon.contentMode = UIViewContentMode.scaleAspectFit
        icon.image = #imageLiteral(resourceName: "Vege")
        prdIngredients.addArrangedSubview(icon)
        stackviewWidth += 25
    }

    if(prdDTO.getSpicyIcn() == "Y")
    {
        let icon = UIImageView()
        icon.contentMode = UIViewContentMode.scaleAspectFit
        icon.image = #imageLiteral(resourceName: "Spicy")
        prdIngredients.addArrangedSubview(icon)
        stackviewWidth += 25
    }

    prdIngredients.widthAnchor.constraint(equalToConstant: CGFloat(stackviewWidth))
Yong Jia Pao
  • 181
  • 1
  • 1
  • 3
0

Remove the trailing constrant (even though XCode complains!!!) and your problem will be solved. This will cause the the view to expand as you add items to it.

enter image description here

Droid Chris
  • 3,455
  • 28
  • 31
-2

Storyboard

  1. Click Attributes Inspector
  2. Select Trailing from the Drop Down menu when Alignment is selected.

Programmatically

  1. Change the UIStackView.alignment property when initializing.
Will Boland
  • 146
  • 2
  • 13