Home > Software design >  How to auto resize tableview height stackview
How to auto resize tableview height stackview

Time:04-07

I'm trying to implement this feature:

Show title, description and image in each cell of a tableview. However, the image could be nil. Requirement is:

  1. When image is nil, auto expand the label to fit the whole cell
  2. Tableview cell height should be adjusted automatically based on the description label.
  3. Need to use stackView

I did this programmatically:

  1. Set this is tableview:

     tableView.rowHeight = UITableView.automaticDimension
     tableView.estimatedRowHeight = 200
    
  2. Create 2 Stackviews: one for labels, one for labels image:

    let contentStack: UIStackView = {
        var view = UIStackView()
        view.axis = .horizontal
        view.spacing = 16
        view.distribution = .equalSpacing
        view.translatesAutoresizingMaskIntoConstraints  = false
        return view }()
    
    let labelStack: UIStackView = {
        var view = UIStackView()
        view.axis = .vertical
        view.spacing = 5
        view.translatesAutoresizingMaskIntoConstraints = false
        view.distribution = .fillProportionally
        return view }()
  1. Use autolayout to setup the constraints:
func setupUI() {
        contentView.addSubview(contentStack)
        labelStack.addArrangedSubview(titleLabel)
        labelStack.addArrangedSubview(descriptionLable)
        contentStack.addArrangedSubview(labelStack)
        contentStack.addArrangedSubview(iconView)
        
        NSLayoutConstraint.activate([

            iconView.heightAnchor.constraint(equalToConstant: 80),
            iconView.widthAnchor.constraint(equalToConstant: 80),

            contentStack.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 16),
            contentStack.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            contentStack.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
            contentStack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -16)
        ])
        layoutIfNeeded()
    }

However, this code doesn't auto resize the height of the tableview cells, you can see from the screenshot, cells won't expand based on the length of the labels.

What's the best way to do this with stackview?

This is what i got so far: enter image description here

CodePudding user response:

A few changes...

Right now, your 80-pt Height image view is limiting the contentStack height to 80-points, so in your contentStack setup, use either:

view.alignment = .top

// or

view.alignment = .center

Change your labelStack setup to:

view.distribution = .fill   // NOT .fillProportionally

make sure you set:

titleLabel.setContentCompressionResistancePriority(.required, for: .vertical)
descriptionLabel.setContentCompressionResistancePriority(.required, for: .vertical)

Edit

This is how it can look with long and short descriptions, and with / without an image. The labels have a cyan background and the image views have a yellow background so you can see the frames...

enter image description here

If that is leaving too much top and bottom "padding" you need to adjust your top and bottom constraint constants.

  • Related