Something seemingly simple turned out to be really hard. I have browsed already multiple topics here and on SnapKit GitHub but failed to solve my issue.
I want to have UITableViewCell
with a label that is positioned in the middle let's say both 50 from top and bottom the cell.
It's worth to mention that the cell is created programatically
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.addSubview(titleLabel)
titleLabel.snp.makeConstraints { (make) -> Void in
make.topMargin.equalToSuperview().offset(50.0)
make.left.equalToSuperview().inset(UIView.getValueScaledByScreenWidthFor(baseValue:10.0))
make.bottomMargin.equalToSuperview().offset(50.0)
}
}
In the ViewController I tried both approaches for automatic cell height:
extension EpisodeViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
}
And
tableView.estimatedRowHeight = 100
tableView.rowHeight = UITableViewAutomaticDimension
in viewDidLoad()
method
What I get is:
Each of these three cells should be populated with "Test" - instead it has pushed down the label below the respective cell without resizing the cell.
Tried many various combinations such as:
1) Setting contraint priority to 999 - no change
2) Adding to contentView instead of self - does not show at all
3) Using top instead of topMargin etc - makes no difference
Could you advice me what's wrong with this code, and what is the general rule of thumb while using SnapKit in programatically created cells that should autoresize its height based on constraint?
Thanks in advance
EDIT
UITableView
DataSource methods
extension EpisodeViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: EpisodeHeaderCell = tableView.dequeueReusableCell(for: indexPath)
cell.viewModel = viewModel
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
label.snp.makeConstraints {
$0.left.equalToSuperview().offset(10)
$0.right.equalToSuperview().offset(-10)
$0.top.equalToSuperview().offset(50)
$0.bottom.equalToSuperview().offset(-50)
}
Here is the whole code of viewController.swift file.
class TestCell: UITableViewCell {
static let identifier: String = "test_cell_identifier"
var label: UILabel!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.configure()
}
func configure() {
label = UILabel(frame: .zero)
self.contentView.addSubview(label)
label.snp.makeConstraints {
$0.left.equalToSuperview().offset(10)
$0.right.equalToSuperview().offset(-10)
$0.top.equalToSuperview().offset(50)
$0.bottom.equalToSuperview().offset(-50)
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class ViewController: UIViewController {
var data: [String] = [
"Test1",
"Test2",
"Test3"
]
var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView = UITableView(frame: .zero)
self.view.addSubview(tableView)
tableView.snp.makeConstraints {
$0.edges.equalToSuperview()
}
tableView.register(TestCell.self, forCellReuseIdentifier: TestCell.identifier)
tableView.dataSource = self
tableView.delegate = self
tableView.estimatedRowHeight = 100
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TestCell.identifier, for: indexPath) as! TestCell
cell.label.text = data[indexPath.item]
return cell
}
}