2

I am having trouble getting content hugging working on a custom view. I have the following code:

pillView.setContentHuggingPriority(.required, for: .horizontal)
pillView.setContentCompressionResistancePriority(.required, for: .horizontal)
dateLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
dateLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

I add these two views to a stack view:

let dateStackView = UIStackView(arrangedSubviews: [pillView, dateLabel])

The result is like so:

enter image description here

The LIVE NOW view should hug it's content. It's defined like so:

final class PillView: UIView {

    private enum Constants {
        static let radius: CGFloat = 4.0
        static let labelInsets = UIEdgeInsets(horizontal: 8.0, vertical: 4.0)
    }

    enum Config {
        case attention

        var font: UIFont {
            switch self {
            case .attention: return Font.caption
            }
        }
        var textColor: UIColor {
            switch self {
            case .attention: return .white
            }
        }
        var backgroundColor: UIColor {
            switch self {
            case .attention: return Theme.red100
            }
        }
    }

    // MARK: - Properties

    private let config: Config

    // MARK: - Initializers

    init(text: String, config: Config = .attention) {
        self.config = config
        super.init(frame: .zero)

        backgroundColor = config.backgroundColor
        clipsToBounds = true
        layer.cornerRadius = Constants.radius

        let label = UILabel()
        label.font = config.font
        label.textColor = config.textColor
        label.text = text

        addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
          label.topAnchor.constraint(equalTo: topAnchor, constant: Constants.labelInsets.top),
          label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -Constants.labelInsets.bottom),
          label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: Constants.labelInsets.left),
          label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -Constants.labelInsets.right)
        ])
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

Not sure why it won't hug the content when in a stack view. Any ideas? Would really appreciate some pointers on this. thanks!

Kex
  • 8,023
  • 9
  • 56
  • 129
  • What does `pin(to:insets:)` do? Can you show its declaration? – Sweeper Dec 10 '20 at 05:07
  • Sorry it was an extension for adding constraints. I updated the question. – Kex Dec 10 '20 at 05:38
  • I can't reproduce this behaviour for some reason... The red label hugs its content as expected for me. – Sweeper Dec 10 '20 at 05:44
  • @Sweeper could you share your code? – Kex Dec 10 '20 at 06:06
  • [Code](https://pastebin.com/nmeTJ4e2) and [output](https://imgur.com/ANgwNqC). Note that the red label does not resist content compression though. – Sweeper Dec 10 '20 at 06:15
  • Thanks. Yeh it needs to not be compressed too. The issue was the label inside the `PillView` that label needs to have the compression and hugging priority set then it works. – Kex Dec 10 '20 at 08:16

2 Answers2

14

Add these lines in your PillView init(...) func:

label.setContentHuggingPriority(.required, for: .horizontal)
label.setContentCompressionResistancePriority(.required, for: .horizontal)

You then don't need to set either of those properties for your pillView or dateLabel instances.

DonMag
  • 69,424
  • 5
  • 50
  • 86
1

Check the distribution property for stackview. It should not be fillEqually as it will ignore the other view's configuration. Mark its value to fill

EDIT:

FillProportionally get me result as: enter image description here

Van
  • 1,225
  • 10
  • 18