14

I'm creating part of my application's UI with Swift and the problem I'm facing is I have a UIStackView with 3 sub views: 2 UILabels and an UIImageView. Here is my first code

let switchview = UISwitch()
let nodelableview = UILabel()
nodelableview.textAlignment = NSTextAlignment.right
nodelableview.numberOfLines = 0
nodelableview.text = nodes[i].type + " " + nodes[i].node_name
let statLabel = UILabel()
statLabel.textAlignment = NSTextAlignment.left
statLabel.text = nodes[i].stat
let stack = UIStackView()
stack.axis = .horizontal
stack.spacing = 16
stack.addArrangedSubview(statLabel)
stack.addArrangedSubview(nodelableview)
stack.addArrangedSubview(switchview)
cell.nodesView.addArrangedSubview(stack)

the problem with this code is that when the nodelabelview has long text the UIStackView not extending to make space for 2 or more lines. So I set the alignment to .center and here is the result enter image description here

There is empty space left but the first UILabel is using it for nothing. How can I force the second UILabel to use available spaces?

Amir_P
  • 8,322
  • 5
  • 43
  • 92
  • 1
    You can try to set the distribution to "Fill Proportionally" and content compression resistance (horizontal) of the left label and the switch to 1000. – Alladinian May 24 '18 at 14:21
  • What does this `cell.nodesView.addArrangedSubview(stack)` line actually do? Are you inserting this horizontal stack view inside another stack view of your cell namely `nodesView`? Why is that necessary? – nayem May 24 '18 at 15:11
  • I have a cell inside my tableview to filter other cells inside tableview and I'm adding filter options to it @nayem – Amir_P May 24 '18 at 18:18
  • thanks that solved my problem. please post it as an answer @Alladinian – Amir_P May 24 '18 at 19:00
  • @Amir_P Done. Glad that helped you :) – Alladinian May 24 '18 at 22:18

2 Answers2

30

A setup that would give priority to your second label (the one with unlimited number of lines), would be a stackview set to "Fill Proportionally" distribution (which means that views are sized based on their intrinsic size & hugging/resistance priorities)

enter image description here

combined with a horizontal "Content Compression Resistance Priority" of 1000 ('required') for the left label & the switch (which means 'do not compress')

enter image description here

which is resolved to this:

enter image description here

Alladinian
  • 34,483
  • 6
  • 89
  • 91
  • Keep in mind that priorities of 1000 are best avoided in content compression where the actual content size is liable to change, since they can very easily break the rest of the layout. This can especially be the case in stack views where the item in question may be set hidden, since stack views use constraints to collapse hidden elements. – Ash May 25 '18 at 12:41
  • @Ash True... but none of these cases was mentioned in the question. Having said that, your point is valid (I cannot count the times I've seen logged warnings due to hidden managed views with 'required' priority). Thanks for your comment :) – Alladinian May 25 '18 at 12:47
  • Yeah, or messed up a stack view because two of the rows have the same hugging / compression values :D – Ash May 25 '18 at 12:50
4

You may need to set the horizontal contentHuggingPriority and contentCompressionResistance for each label / switch to something different from the others, ensuring that the one you wish to expand to fill remaining available space has the lowest hugging value.

Ash
  • 9,064
  • 3
  • 48
  • 59
  • 1
    When you add a view to a container view, it is the container view's responsibility to control `translatesAutoresizingMaskIntoConstraints`. – Ken Thomases May 24 '18 at 16:20
  • That's nice to know, although I think the rest of the answer remains relevant. I've edited my answer to reflect this. I won't echo Alladinian's response. – Ash May 25 '18 at 12:36