Search code examples
swiftuitableviewuikituilabel

Inside custom tableView cell: UILabel's background is beyond the text length (programmatically)


I create a tableView with custom cell, which contains two labels programmatically. And I cannot get left label's text aligned with its background. May need some help from your guys.

In order to narrow down the problem then I create a small project to do a few experiments:

Inside ViewController:

  • If with tableView.rowHeight = 40, get below result, which is not what I want. The left label's background is beyond the text length.

enter image description here

  • If comment out line tableView.rowHeight = 40, get below result, which is what I want but with a warning in console.

"[Warning] Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a table view cell's content view. We're considering the collapse unintentional and using standard height instead."

enter image description here

  • Also try to use below statement, it gets the same display on screen with scenario 2. However, it has the same warning there as scenario 2.
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 40

ViewController

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var tableView = UITableView()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let uiView = UIView()
        uiView.backgroundColor = .systemBackground
        view = uiView
        
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(CustomCell.self, forCellReuseIdentifier: "countryDetail")
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.rowHeight = 40
        view.addSubview(tableView)
        
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
            tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
            tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
        ])
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 8
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "countryDetail", for: indexPath) as? CustomCell else {
            fatalError("Unable to dequeue CustomCell")
        }
        
        cell.name.text = "Country: "
        cell.value.text = "US"
        
        return cell
    }
}

CustomCell

import UIKit

class CustomCell: UITableViewCell {
    var name = UILabel()
    var value = UILabel()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: "countryDetail")
        
        name.translatesAutoresizingMaskIntoConstraints = false
        name.numberOfLines = 0
        name.textAlignment = .left
        name.layer.masksToBounds = true
        name.layer.cornerRadius = 5
        name.backgroundColor = .systemGreen
        name.font = UIFont(name: "Helvetica Neue", size: 22)
        contentView.addSubview(name)
        
        value.translatesAutoresizingMaskIntoConstraints = false
        value.numberOfLines = 0
        value.textAlignment = .left
        value.font = UIFont(name: "Helvetica Neue", size: 18)
        contentView.addSubview(value)
        
        NSLayoutConstraint.activate([
            name.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
            name.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            
            value.leadingAnchor.constraint(equalTo: name.trailingAnchor, constant: 10),
            value.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
            value.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Solution

  • Oh, it is a silly mistake. I should remove this line value.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10) from CustomCell to remove right label's trailing anchor constraint as I want the right label left aligned to the left one.

    And this time using tableView.rowHeight = 40, the app works fine.