简体   繁体   中英

Change height priority of UIImageView inside UIStackView

I have an UIImageView inside UIView which is inside an horizontal UIStackView (with.fillEqually option). Horizontal UIStackView has two views always. Horizontal UIStackView gets its height from the Its' highest sub UIView .

What I want to achieve: In the example screenshot, UIImageView has a bigger size when you consider with the multiline views because of its image size. However, I want that image view shrinks to the size that fits left (multiline label) view. This is shown in the second screenshot. Image should has a height of which I show via red oval line on the right side.

UIImageView with label Class:

@IBDesignable class LabelWithImage: UIView {

var topMargin: CGFloat = 0.0
var verticalSpacing: CGFloat = 10.0
var bottomMargin: CGFloat = 0.0

@IBInspectable var labelText: String = "" { didSet { updateView() } }
@IBInspectable var image: UIImage = UIImage(named: "harcamagrafik")! { didSet { updateView() } }

fileprivate var label: UILabel!
fileprivate var imageView: UIImageView!

override init(frame: CGRect) {
    super.init(frame: frame)
    setUpView()
}

required public init?(coder: NSCoder) {
    super.init(coder:coder)
    setUpView()
}

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setUpView()
}

func setUpView() {

    label = UILabel()
    label.font = UIFont.init(name: "Metropolis-Medium", size: 12)
    label.numberOfLines = 1
    label.lineBreakMode = NSLineBreakMode.byWordWrapping
    label.textColor = UIColor.init(rgb: 0x9B9B9B)

    imageView = UIImageView(image: image)
    imageView.contentMode = .scaleAspectFill
    imageView.clipsToBounds = true

    addSubview(label)
    addSubview(imageView)

    label .translatesAutoresizingMaskIntoConstraints = false
    imageView.translatesAutoresizingMaskIntoConstraints = false
    setContentHuggingPriority(.init(rawValue: 1000.0), for: .vertical)
    setContentCompressionResistancePriority(.init(rawValue: 10.0), for: .vertical)

    label.leftAnchor.constraint(equalTo: leftAnchor, constant: 0.0).isActive = true
   // imageView.leftAnchor.constraint(equalTo: leftAnchor, constant: 0.0).isActive = true

    label.rightAnchor.constraint(equalTo: rightAnchor, constant: 0.0).isActive = true
   // imageView.rightAnchor.constraint(equalTo: rightAnchor, constant: 0.0).isActive = true

    imageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
    label.topAnchor.constraint(equalTo: topAnchor, constant: topMargin).isActive = true
    imageView.topAnchor.constraint(equalTo: label.bottomAnchor, constant: verticalSpacing).isActive = true
    bottomAnchor.constraint(equalTo: imageView.bottomAnchor, constant: bottomMargin).isActive = true

    // call common "refresh" func
    updateView()
}

func updateView() {
    label.text = labelText
    accessibilityIdentifier = labelText
    imageView.image = image
    label.sizeToFit()
}
}

Horizontal StackView:

private let topHorizontalStackView: UIStackView = {
let s = UIStackView()
s.distribution = .fillEqually
s.spacing = 10
s.axis = .horizontal
s.alignment = .fill
s.translatesAutoresizingMaskIntoConstraints = false
return s
}()

EDIT I tried to set a height constraint to my LabelWithImage view. Now, It looks ok but when I open the debugger, It says that height is ambiguous for the view.

leftView.layoutIfNeeded() //It is the view with multilineLabel.
view.heightAnchor.constraint(equalToConstant: leftView.bounds.height).isActive = true

示例视图

What I want shown in screenshot:

SS2

EDIT 2 After I give priority to label as @Don said and set compression to low on image view, I got below result. Below code is still active by the way

leftView.layoutIfNeeded() //It is the view with multilineLabel. view.heightAnchor.constraint(equalToConstant: leftView.bounds.height).isActive = true

If I give specific constant to labelWithImageView as (40 is UIStackView top and bottom insets);

view.heightAnchor.constraint(equalToConstant: leftView.bounds.height - 40).isActive = true

Views inside top vertical UIStackView shows ambitious layout. (You can't see that views inside screenshots because I guess those are not related.) ss3

Well, it just looks like your constraints are wrong, here I've made an example with screen attached so you can recreate my constraints

Here's an explanation: in left view set your own constraints to fill the view (check for ambiguity since right view is supposed to get the size from the left one), set all labels inside it with vertical content hugging priority to 1000

on right one you simply need to set the title vertical content hugging priority to 1000 (+ basic needed constraints like leading, trailing and top to fill the view) and viola, image will morph into whatever size needed to match left view's size.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM