I would like to have a similar behavior than the <Table>
HTML tag, in the sense where the frame is sized according to its content.
In my very context, I use an UIStackView as the content view of a UITableViewCell. As items in the cell are various information, the resulting height of the cell should be variable.
My strategy is to programmatically build a cell as a UIStackView with a .Vertical axis, as in the code snippet as follows:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let sv = UIStackView(frame: tableview.frame)
sv.axis = .Vertical
cell.addSubview(sv)
for i in information {
let l = UILabel()
l.text = i
sv.addSubViewAndArrange(l)
}
return cell
}
Unfortunately, the cell size does not adjust to the content, and as a result I have to set the cell height myself, as follows:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return cellHeight // a constant
}
How could I fix that?
Managing SubviewsStack views don't have an intrinsic content size, so you must set it either implicitly with Auto Layout constraints or explicitly via its intrinsicContentSize property.
You use a UIStackView to group UI elements together to simplify setting constraints. In other words once you've added objects to the stack view, you constrain the stackview and set attributes on it rather than on each individual element.
Overview. Stack views let you leverage the power of Auto Layout, creating user interfaces that can dynamically adapt to the device's orientation, screen size, and any changes in the available space. The stack view manages the layout of all the views in its arrangedSubviews property.
UIStackView
is designed to grow its size according to the content. In order for that to work, you need to set up the constraints between the UIStackView
and the UITableViewCell
. For example, if UIStackView
is first-item and UITableViewCell
is it's super-view, then this is how the constraints look like in interface builder:
If you like setting up constraints in code, that should work too.
For example, assuming stackView
and cellView
are the names, then above constraints' Swift-code would look like:
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.topAnchor.constraint(equalTo: cellView.topAnchor, constant: 0).isActive = true
stackView.bottomAnchor.constraint(equalTo: cellView.bottomAnchor, constant: 0).isActive = true
stackView.leadingAnchor.constraint(equalTo: cellView.leadingAnchor, constant: 0).isActive = true
stackView.trailingAnchor.constraint(equalTo: cellView.trailingAnchor, constant: 0).isActive = true
To demonstrate that this will work, I have this for the cellForRowAt
function. Basically, it puts a number of UILabel
inside the UIStackView
and the label count is depending on the row number.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableviewCell", for: indexPath) as! TableviewCell
for i in 1...indexPath.row + 1 {
let label = UILabel()
label.text = "Row \(indexPath.row), Label \(i)"
cell.stackView.addArrangedSubview(label)
}
return cell
}
Here is the final result:
https://github.com/yzhong52/AutosizeStackview
I built this example I hope it helps, I've created a tableView which use a cell that contains a stackView and the views loaded in the stackView are gotten from a nib file
https://github.com/Joule87/stackView-within-TableViewCell
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With