Пара вещей ...
- НЕ устанавливайте
.translatesAutoresizingMaskIntoConstraints
на cell
или .contentView
- Вы устанавливаете ограничения
leading
и trailing
для стекового представления, поэтому нет необходимости устанавливать его width
- Отсутствует ограничение
bottom
Попробуйте:
class SalesPointTableViewCell: UITableViewCell {
private var nameLabel = UILabel()
private var someView: UIStackView = {
$0.distribution = .fill
// add a little spacing between arranged subviews so we can see them
$0.spacing = 4
$0.translatesAutoresizingMaskIntoConstraints = false
$0.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
return $0
}(UIStackView())
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// no no no
//translatesAutoresizingMaskIntoConstraints = false
// no no no
//contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(nameLabel)
contentView.addSubview(someView)
nameLabel.snp.makeConstraints {
$0.left.top.equalToSuperview()
}
// you're missing a bottom constraint
//someView.snp.makeConstraints {
// $0.left.right.width.equalToSuperview()
// $0.top.equalTo(nameLabel.snp.bottom)
//}
someView.snp.makeConstraints {
// costraining left and right, so no need for width
// $0.left.right.width.equalToSuperview()
$0.left.right.equalToSuperview()
$0.top.equalTo(nameLabel.snp.bottom)
// need to add a bottom constraint
$0.bottom.equalToSuperview()
}
// give nameLabel a cyan background to make it easy to see the frame
nameLabel.backgroundColor = .cyan
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForReuse() {
super.prepareForReuse()
nameLabel.text = nil
someView.arrangedSubviews.forEach {$0.removeFromSuperview()}
}
func configure(name: String, points: [String]) {
self.nameLabel.text = name
points.forEach { pointName in
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
// give labels a green background to make it easy to see the frames
label.backgroundColor = .green
label.textAlignment = .center
label.numberOfLines = 1
label.text = pointName
self.someView.addArrangedSubview(label)
// sizeToFit is not needed
//label.sizeToFit()
}
}
}
class SalesTableViewController: UITableViewController {
var theData: [[String]] = [[String]]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(SalesPointTableViewCell.self, forCellReuseIdentifier: "SPCell")
// generate 50 "sales points"
// each "sales point" will have 1, 2 or 3 labels
for i in 1...50 {
let n = Int.random(in: 1...3)
var a: [String] = [String]()
for j in 1...n {
a.append("Point: \(i) / \(j)")
}
theData.append(a)
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return theData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "SPCell", for: indexPath) as! SalesPointTableViewCell
let a = theData[indexPath.row]
cell.configure(name: "Test \(indexPath.row)", points: a)
return cell
}
}
Результат:
и, после прокрутки, чтобы вы могли видеть, что они используются повторно: