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:
- When image is nil, auto expand the label to fit the whole cell
- Tableview cell height should be adjusted automatically based on the description label.
- Need to use stackView
I did this programmatically:
Set this is tableview:
tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 200
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 }()
- 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?
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...
If that is leaving too much top and bottom "padding" you need to adjust your top and bottom constraint constants.