Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableViewCell with StackView not dynamically sizing height

I have a custom UITableViewCell that contains a StackView with top, bottom, leading and trailing constraints to the content view of the cell.

When I set up my tableView, I give it an estimated height and also set the rowHeight to UITableViewAutomaticDimension.

In my cellForRowAt datasource method, I dequeue the cell and then call cell.setup() which adds any given number of views to my cell's stackView.

The problem is: My cell is always being sized to the estimated height of 80p. No matter how many views I add to the cell's stackView, it all crams into 80p height. The stackView, and thus the cell, isn't growing with each new item I insert into the cell before returning it in cellForRowAt datasource method.

I tried different distribution settings for my stackView, but I'm not sure what I'm doing wrong here.

like image 483
Brejuro Avatar asked Jul 10 '18 19:07

Brejuro


1 Answers

Here is a simple demonstration of adding buttons to a stack view inside an auto-sizing table view cell:

class StackOfButtonsTableViewCell: UITableViewCell {

    @IBOutlet var theStackView: UIStackView!

    func setup(_ numButtons: Int) -> Void {

        // cells are reused, so remove any previously created buttons
        theStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }

        for i in 1...numButtons {
            let b = UIButton(type: .system)
            b.setTitle("Button \(i)", for: .normal)
            b.backgroundColor = .blue
            b.setTitleColor(.white, for: .normal)
            theStackView.addArrangedSubview(b)
        }

    }

}


class ViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 100
    }

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

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

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

        let cell = tableView.dequeueReusableCell(withIdentifier: "StackOfButtonsTableViewCell", for: indexPath) as! StackOfButtonsTableViewCell

        cell.setup(indexPath.row + 1)

        return cell

    }

}

Assuming you have created a prototype cell, and its only content is a UIStackView configured as:

Axis: Vertical
Alignment: Fill
Distribution: Equal Spacing
Spacing: 8

and you have it constrained Top/Leading/Trailing/Bottom to the cell's content view, this is the result:

enter image description here

No need for any height calculations, and, since buttons do have intrinsic size, no need to set height constraints on the buttons.

like image 61
DonMag Avatar answered Oct 23 '22 02:10

DonMag