My Problems: I'm trying to set auto height to my table cell. However, when I using tableView.rowHeight = UITableView.automaticDimension
or func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableView.automaticDimension }
. As shown on image, I got 0 height for my tableView; but if I set the tableView's height at autoLayout, I can see my tableView again.(which is not right because I want height to be dynamic, the button and the view should at bottom of table view.)
Here is My ViewController Code:
class ViewController: UIViewController {
var dataSource = ["1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2", "1", "2",]
private lazy var scrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.delegate = self
scrollView.showsVerticalScrollIndicator = false
scrollView.showsHorizontalScrollIndicator = false
scrollView.contentInsetAdjustmentBehavior = .never
scrollView.bounces = false
return scrollView
}()
private lazy var tableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .plain)
tableView.backgroundColor = .clear
tableView.delegate = self
tableView.dataSource = self
tableView.register(TestTabelCell.self, forCellReuseIdentifier: TestTabelCell.identifier)
tableView.rowHeight = UITableView.automaticDimension
return tableView
}()
private lazy var moreBtn: UIButton = {
let button = UIButton()
button.setTitle("Click for More", for: .normal)
button.setTitleColor(UIColor.green, for: .normal)
return button
}()
private lazy var bottomView: UIView = {
let view = UIView()
view.backgroundColor = .brown
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setupUI()
}
func setupUI() {
view.addSubview(scrollView)
scrollView.addSubview(tableView)
scrollView.addSubview(moreBtn)
scrollView.addSubview(bottomView)
scrollView.snp.makeConstraints { make in
make.top.leading.trailing.equalToSuperview()
make.bottom.equalToSuperview()
}
stackView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
tableView.snp.makeConstraints { make in
make.top.equalToSuperview()
make.leading.trailing.equalToSuperview()
}
moreBtn.snp.makeConstraints { make in
make.top.equalTo(tableView.snp.bottom)
make.leading.trailing.equalToSuperview()
make.height.equalTo(20)
}
bottomView.snp.makeConstraints { make in
make.top.equalTo(moreBtn.snp.bottom)
make.leading.trailing.equalToSuperview()
make.width.equalTo(390)
make.height.equalTo(400)
make.bottom.equalToSuperview()
}
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TestTabelCell.identifier, for: indexPath)
if let cell = cell as? TestTabelCell {
cell.updateUI(String(indexPath.row))
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
print("print", UITableView.automaticDimension)
return UITableView.automaticDimension
}
}
and Here is My Cell Code:
class TestTabelCell: UITableViewCell {
static let identifier = "ParlorJourneyListCell"
private lazy var label: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 12)
label.textColor = .black
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier)
setupUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupUI() {
addSubview(label)
label.snp.makeConstraints { make in
make.top.equalToSuperview().inset(8)
make.height.equalTo(20)
make.bottom.equalToSuperview()
}
}
func updateUI(_ num: String) {
label.text = "Test Num: \(num)"
}
}
CodePudding user response:
Actually, you're calculating just table view cell height, not table view height itself. You have to recalculate table view height every time reloadData()
get called. I assume that the cell's autolayout is correct. There are few steps to do:
func viewDidLoad() {
...
//Added listener to your table view contentSize if changed
tableView.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)
}
//Then override this function to update table view height
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard keyPath == "contentSize" else { return }
guard
let newValue = change?[.newKey],
let newHeight = (newValue as? CGSize)?.height else { return }
tableView.snp.updateConstraints {
$0.height.equalTo(newHeight)
}
}
CodePudding user response:
You need to add your cell's subviews in the contentView of the cell. And make constraints based on contentView.
func setupUI() {
contentView.addSubview(label)
label.snp.makeConstraints { make in
make.top.equalToSuperview().inset(8)
make.height.equalTo(20)
make.bottom.equalToSuperview()
}
}
Change your code like this and try now!
contentView.addSubview(label)