Isuru
Isuru

Reputation: 31283

UITableViewCell height not dynamically being calculated even with all the constraints added

I'm trying to create a custom UItableViewCell with three labels. Two of them on the left side (like the built-in title + subtitle layout) and the other one at the right side. I'm laying out the labels programatically.

class CustomCell: UITableViewCell {
    static let identifier = String(describing: self)
    
    lazy var primaryLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.preferredFont(forTextStyle: .body)
        return label
    }()
    
    lazy var secondaryLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.preferredFont(forTextStyle: .footnote)
        return label
    }()
    
    lazy var tertiaryLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.preferredFont(forTextStyle: .callout)
        return label
    }()
    
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        setup()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setup() {
        contentView.addSubview(primaryLabel)
        contentView.addSubview(secondaryLabel)
        contentView.addSubview(tertiaryLabel)
        
        NSLayoutConstraint.activate([
            tertiaryLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
            tertiaryLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
            tertiaryLabel.heightAnchor.constraint(equalToConstant: 18),
            
            primaryLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            primaryLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 12),
            primaryLabel.heightAnchor.constraint(equalToConstant: 19),

            secondaryLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
            secondaryLabel.topAnchor.constraint(equalTo: primaryLabel.bottomAnchor, constant: 8),
            secondaryLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 12),
//            secondaryLabel.heightAnchor.constraint(equalToConstant: 15)
        ])
    }
}

I want the cell's height to be calculated dynamically. I set the rowHeight and estimatedRowHeight property values to UITableView.automaticDimension in the view controller when I instantiate the table view.

private lazy var tableView: UITableView = {
    let tableView = UITableView(frame: view.bounds, style: .grouped)
    tableView.allowsSelection = false
    tableView.dataSource = self
    tableView.delegate = self
    tableView.rowHeight = UITableView.automaticDimension
    tableView.estimatedRowHeight = UITableView.automaticDimension
    tableView.register(CustomCell.self, forCellReuseIdentifier: CustomCell.identifier)
    return tableView
}()

But the cell still shows up like this. With the default height. Even though I have auto layout constraints laid out from top to bottom. I get no warnings in the console either.

Any idea what I am missing here?

enter image description here

Demo project

Upvotes: 1

Views: 33

Answers (1)

Rob
Rob

Reputation: 437492

Two observations:

  1. Your secondary label needs a negative constant to the bottom of the container.

  2. Also, your estimated row height should be some reasonable fixed value (e.g 44 or something like that ... it doesn't need to be perfect, but just some reasonable value that the table can use for estimating the height of rows that haven't been presented yet). You do not want to use UITableView.automaticDimension for estimatedRowHeight, only for rowHeight.

Upvotes: 1

Related Questions