1
votes

I have the following 3 components within a Horizontal stack view.

  1. Yellow UILabel
  2. Red UIImageView
  3. Green UIImageView

The distribution for the Horizontal stack view is Fill.

The content mode for UIImageView is Aspect fit. They are using SFSymbol named "pin.fill".

The number of line for UILabel is 0, so that it supports multilines.

All the 3 components are having same Content Hugging Priority (250) and Content Compression Resistance Priority (750)

When Horizontal Content Compression Resistance for UILabel is 750 to 998

enter image description here

enter image description here


My questions are

  1. Why the red UIImage take up most space, even though all 3 of them are having same Content Hugging Priority (250) and Content Compression Resistance Priority (750)?
  2. My intention is letting yellow UILabel fill up most space. However, I can only achieve so, if I increase the Horizontal Content Compression Resistance (For UILabel only) up to 999 or 1000. I thought, as long as any value is higher than 750 will be good enough? Does 999 or 1000 value in Horizontal Content Compression Resistance carry any special meaning?

When Horizontal Content Compression Resistance for UILabel is 999 or 1000

enter image description here

Please do take note that, even when Horizontal Content Compression Resistance for UILabel is 999 or 1000, both red & green UIImageView's width will be compressed. But, they are compressed with different strength, which end up 2 UIImageView are having slightly different width. Why?


p/s

The complete project code is located at https://github.com/yccheok/stackoverflow/tree/master/66444344/test

1
Have you given your image views a width and/or height constraint? What Content Mode are they using - Aspect Fill? What size is the actual thumb-tack image? - DonMag
The content mode for UIImageView is Aspect fit. - Cheok Yan Cheng
@DonMag I also post a complete project code for your reference purpose. Thanks. - Cheok Yan Cheng

1 Answers

1
votes

You're over-thinking things a bit.

What you want to do is tell the two image views to "hug" their content, and leave everything else at the default Hugging and Compression Resistance values.

So, Label properties:

enter image description here

Both "pin" image views:

enter image description here

It will look like this in your Storyboard:

enter image description here

Give this code a try... connect the label to the @IBOutlet and run the app. Each tap will cycle through 4 different length strings for the label:

class ViewController: UIViewController {
    
    @IBOutlet var label: UILabel!
    
    let strs: [String] = [
        "Very Short",
        "A little longer, but still one line.",
        "Button - You can set the title, image, and other appearance properties of a button.",
        "UIStackView - creates and manages the constraints necessary to create horizontal or vertical stacks of views. It will dynamically add and remove its constraints to react to views being removed or added to its stack. With customization it can also react and influence the layout around it.",
    ]
    
    var idx: Int = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.text = strs[idx % strs.count]
        
        // tap anywhere in the view
        let t = UITapGestureRecognizer(target: self, action: #selector(gotTap(_:)))
        view.addGestureRecognizer(t)
        
    }
    
    @objc func gotTap(_ g: UITapGestureRecognizer) -> Void {
        idx += 1
        label.text = strs[idx % strs.count]
    }
    
}

and the result will be:

enter image description here

enter image description here

enter image description here

enter image description here