user2747220 user2747220 - 2 months ago 33
iOS Question

Stack View in a table view cell

I am trying to implement a stack view inside a table view cell programmatically and add labels and buttons to it like so:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let dict = self.char[indexPath.row]
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.spacing = 20
stackView.distribution = .fillProportionally
stackView.alignment = .leading
cell.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: cell.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: cell.trailingAnchor)
])
let bornLabel = UILabel()
bornLabel.textColor = UIColor.blue
let bornLabelValue = UILabel()
bornLabelValue.textColor = UIColor.blue
stackView.addArrangedSubview(bornLabel)
stackView.addArrangedSubview(bornLabelValue)
for (key, value) in dict {
bornLabel.text = key
bornLabelValue.text = value
if key == "Height" {
let button = UIButton(type: .roundedRect)
button.setTitle("English", for: .normal)
button.setTitleColor(.blue, for: .normal)
stackView.addArrangedSubview(button)
}
}
return cell
}


The problem is that every time
tableView.reloadData()
is called, another cell is added on top of the existing one with different values for each label depending on the data given to the tableView. Or it might not generate another cell every time but just add another stackview. I'm not sure. How can I fix this?

Thanks

Answer

The problem is that you're getting a "reusable cell", that means it'll be an empty cell the first few times, and then it'll be a cell where you already added a UIStackView.

You should make a new prototype cell, either via the Storyboard or a new XIB file, add the UIStackView in it, and then only configure that stackView in your cellForRowAt indexPath: implementation.

Or you could technically set a tag in the stackView, and then check the cell for that tag… but please don't do this.