UIStackView content hugging is not working as expected in UITableViewCell
Asked Answered
M

1

10

I have two vertical StackView nested in horizontal StackView.
For the first one:

titlesView.axis = .vertical
titlesView.distribution = .fill
titlesView.alignment = .leading

And the second one:

checkView.axis = .vertical
checkView.distribution = .fil
checkView.alignment = .center

and for holderStackView(root)

    holderStackView.axis = .horizontal
    holderStackView.alignment = .center
    holderStackView.distribution = .fill


    holderStackView.addArrangedSubview(titlesView)
    holderStackView.addArrangedSubview(checkView)


    titlesView.setContentHuggingPriority(.defaultLow, for: .horizontal)
    checkView.setContentHuggingPriority(.defaultHigh, for: .horizontal)

I expect the titlesView must fill the StackView, but the checkView StackView fills the holderStackView stack view.

if I set alignment for both of them center or leading, then it works as expected and the first one grows.



Expectation:

enter image description here



Reality:

enter image description here



How can I fix this problem?

It happens only in the contentView of the UITableViewCell, see the minimal example below:

class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.separatorColor = UIColor(red:0.87, green:0.87, blue:0.87, alpha:1.00)
        tableView.estimatedRowHeight = 150
        tableView.backgroundColor = UIColor.clear
        tableView.rowHeight = UITableViewAutomaticDimension

        self.view.backgroundColor = UIColor(red:0.93, green:0.93, blue:0.93, alpha:1.00)
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 6
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return MedicationHomeCell()
    }
}



class MedicationHomeCell: UITableViewCell {

    let holderStackView = UIStackView()
    let checkView = UIStackView()
    let titlesView = UIStackView()

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        layoutViews()
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        layoutViews()
    }

    func layoutViews() {
        self.contentView.backgroundColor = .white

        self.contentView.addSubview(holderStackView)
        holderStackView.addArrangedSubview(titlesView)
        holderStackView.addArrangedSubview(checkView)

        titlesView.axis = .vertical
        titlesView.distribution = .fill
        titlesView.alignment = .leading

        checkView.axis = .vertical
        checkView.distribution = .fill
        checkView.alignment = .center

        holderStackView.axis = .horizontal
        holderStackView.alignment = .center
        holderStackView.distribution = .fill


        titlesView.setContentHuggingPriority(.defaultLow, for: .horizontal)
        checkView.setContentHuggingPriority(.defaultHigh, for: .horizontal)

        holderStackView.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            holderStackView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor),
            holderStackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor),
            holderStackView.topAnchor.constraint(equalTo: self.contentView.topAnchor),
            holderStackView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor)
            ])


        for index in 0..<2 {
            let label = UILabel()
            label.text = "Label \(index)"
            label.backgroundColor = .red
            titlesView.addArrangedSubview(label)
        }

        for index in 0..<2 {
            let label = UILabel()
            label.text = "Text \(index)"
            label.backgroundColor = .green
            checkView.addArrangedSubview(label)
        }
    }
}
Mize answered 10/12, 2017 at 13:49 Comment(5)
did you set the proper content hugging (horizontal)? +I would prefer to see the codeLatreshia
@MilanNosáľ , I edit and add some codeMize
I've updated your code to make it easier to try it out for others. I'm having the same issue and as of right now I have no idea why is it behaving like this.Latreshia
Did you find the answer ? I have the same problem, I can't explainTomasatomasina
unfortunately, no.Mize
C
13

UIStackViews don't seem to respect the content hugging and resistance compression properties. Instead, set these properties on each arranged subview.

For nested stack views, you may need to drill down to their non-stack arranged subviews, and set the properties there.

Ceres answered 12/2, 2019 at 3:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.