David Kroukamp
David Kroukamp

Reputation: 36423

UIStackView dynamcially add 2 labels next to each other with no extra spacing

Im new to iOS development and Im a bit confused as to how to achieve this.

I have 2 UILabels added to a UIStackView like so:

let horizontalStackView1 = UIStackView(arrangedSubviews: [self.label1, self.label2])

and when I run the app it looks like this:

enter image description here

However, Id like the labels to be next to each other with no spacing in between something like this: enter image description here

Ive tried setting horizontalStackView1.distribution, horizontalStackView1.alignment etc with no luck.

How do I achieve this?

Thanks in advance!

UPDATE:

The code looks like this (its a cell of a table by the way):

class ItemTableViewCell: UITableViewCell
{
    ...
    let stateLabel = UILabel()
    let effectiveDateLabel = UILabel()
    ...

    var typeImage: UIImage?
    {
        ...
    }

    var summary: String?
    {
        ...
    }

    var effectiveDate: Date?
    {
        ...
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?)
    {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.accessoryType = .disclosureIndicator
        ...
        let horizontalStackView1 = UIStackView(arrangedSubviews: [self.stateLabel, self.effectiveDateLabel])
        let horizontalStackView2 = UIStackView(arrangedSubviews: [typeImageViewWrapper, self.titleLabel])
        horizontalStackView2.spacing = 4
        let verticalStackView = UIStackView(arrangedSubviews: [horizontalStackView1, horizontalStackView2, self.summaryLabel])
        verticalStackView.axis = .vertical
        verticalStackView.spacing = 4
        self.contentView.addSubview(verticalStackView)
        ...
    }

    required init?(coder aDecoder: NSCoder)
    {
        fatalError()
    }
}

Upvotes: 3

Views: 3870

Answers (2)

zisoft
zisoft

Reputation: 23078

The stackviews distribution should be set to fillProportionally so every arranged subview keeps its proportions.

However, the remaining space is filled by the stackview automatically. To suppress this, you need to add an empty view at the end. This empty view needs a low content hugging priority so it can grow to fill up the space where the other views remain by their proportions.

Furthermore, the empty view needs an intrinsicContentSize for the stackview to compute the dimensions:

class FillView: UIView {
    override var intrinsicContentSize: CGSize {
        get { return CGSize(width: 100, height: 100) }
    }
}

Now set your arranged subviews and put the fillView at the end

let fillView: UIFillView()
fillView.setContentHuggingPriority(priority: .fittingSizeLevel, for: .horizontal)
myStackView.addArrangedSubview(fillView)

Set the stackviews spacing to your needs to maintain the distance between the subviews.

Upvotes: 0

Michal Klein
Michal Klein

Reputation: 338

That's because the UIStackView picks the first arrangedSubview with lowest content hugging priority and resizes it so the stackview's content takes up full width.

If you want to use UIStackView for this case, you can should change the content hugging priorities, eg.

label2.setContentHuggingPriority(.defaultLow, for: .horizontal)
label1.setContentHuggingPriority(.defaultHigh, for: .horizontal)

Upvotes: 6

Related Questions