Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent vertical UIStackView from stretching a subview?

I have a UITableViewCell with a vertical UIStackView that currently has .alignment = fill and distribution = fill. Inside the stack view, I have a UILabel and a UIImageView.

enter image description here

The label should be left aligned and stretch across the width of the stackview (and it does). The image view has a content mode of aspect fit and should be centered in the middle of the stackview. I thought this was working as I wanted it to until I set a background color on the UIImageView and then realized that while the image itself appears correct (scaled and centered) the view itself stretches across the full width of the stackview (just like the label does).

Is it possible to have the label stretch the width of the stack view but not the image view? Ideally, I'd like the image view to just be the size of the scaled image and not stretch all the way to the edges of the stack view.

like image 312
bmt22033 Avatar asked Dec 13 '22 14:12

bmt22033


1 Answers

Make these changes:

  1. Set your stack view's alignment to .center instead of .fill.
  2. Constrain the label's width to equal the stack view's width.
  3. In code, when you set the image view's image, also create an aspect-ratio constraint on the image view, like this:

    class MyCell: UITableViewCell {
        @IBOutlet private var myImageView: UIImageView!
        private var imageViewAspectConstraint: NSLayoutConstraint?
    
        func setImage(_ image: UIImage) {
            myImageView.image = image
    
            imageViewAspectConstraint?.isActive = false
            imageViewAspectConstraint = myImageView.widthAnchor.constraint(
                equalTo: myImageView.heightAnchor,
                multiplier: image.size.width / image.size.height)
            imageViewAspectConstraint!.isActive = true
        }
    }
    

Note that, since cells can be reused, you also have to remove a prior aspect-ratio constraint if there is one. The code I posted uses imageViewAspectConstraint to save the constraint and remove it when the image changes.

like image 152
rob mayoff Avatar answered Jan 12 '23 18:01

rob mayoff