-1

I created table view cell programmatically and set the constrains as well.It is able to display the image , firstname , lastname property into cell but when I added new label with values , it not displaying the values .

Here is the cell code .

import UIKit

class PeopleCell: UITableViewCell {

    
    static let identifier = "PeopleCell"
    
    let containerView:UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.clipsToBounds = true // this will make sure its children do not go out of the boundary
        return view
    }()
    
    let profileImageView:UIImageView = {
        let img = UIImageView()
        img.contentMode = .scaleAspectFill // image will never be strecthed vertially or horizontally
        img.translatesAutoresizingMaskIntoConstraints = false // enable autolayout
        img.layer.cornerRadius = 35
        img.clipsToBounds = true
        return img
    }()
    
    let firstnameTitleLabel:UILabel = {
        let label = UILabel()
        label.font = UIFont.boldSystemFont(ofSize: 20)
        label.textColor = .black
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let lastnameTitleLabel:UILabel = {
        let label = UILabel()
        label.font = UIFont.boldSystemFont(ofSize: 14)
        label.textColor =  .white
        label.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1)
        label.layer.cornerRadius = 5
        label.clipsToBounds = true
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    let jobTitleLabel:UILabel = {
        let label = UILabel()
        label.font = UIFont.boldSystemFont(ofSize: 20)
        label.textColor = .black
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        self.contentView.addSubview(profileImageView)
        containerView.addSubview(firstnameTitleLabel)
        containerView.addSubview(lastnameTitleLabel)
        containerView.addSubview(jobTitleLabel)
        self.contentView.addSubview(containerView)
         
        profileImageView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
        profileImageView.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor, constant:10).isActive = true
        profileImageView.widthAnchor.constraint(equalToConstant:70).isActive = true
        profileImageView.heightAnchor.constraint(equalToConstant:70).isActive = true
        
        containerView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
        containerView.leadingAnchor.constraint(equalTo:self.profileImageView.trailingAnchor, constant:10).isActive = true
        containerView.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor, constant:-10).isActive = true
        containerView.heightAnchor.constraint(equalToConstant:40).isActive = true
        
        firstnameTitleLabel.topAnchor.constraint(equalTo:self.containerView.topAnchor).isActive = true
        firstnameTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        firstnameTitleLabel.trailingAnchor.constraint(equalTo:self.containerView.trailingAnchor).isActive = true
        
        lastnameTitleLabel.topAnchor.constraint(equalTo:self.firstnameTitleLabel.bottomAnchor).isActive = true
        lastnameTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        lastnameTitleLabel.topAnchor.constraint(equalTo:self.firstnameTitleLabel.bottomAnchor).isActive = true
        lastnameTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        
        jobTitleLabel.topAnchor.constraint(equalTo:self.lastnameTitleLabel.bottomAnchor).isActive = true
        jobTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        jobTitleLabel.topAnchor.constraint(equalTo:self.lastnameTitleLabel.bottomAnchor).isActive = true
        jobTitleLabel.leadingAnchor.constraint(equalTo:self.containerView.leadingAnchor).isActive = true
        
    }
   
    
   required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configureCell(firstName: String, lastName: String,jobtitle: String ) {
        firstnameTitleLabel.text = "Firstname :\(firstName)"
        lastnameTitleLabel.text = "Lastname : \(lastName)"
        jobTitleLabel.text = "Occupation : \(jobtitle)"
      
        
        }
    func configureImageCell(row: Int, viewModel: ViewModel) {
        
        profileImageView.image = nil
        
        viewModel
            .downloadImage(row: row) { [weak self] data in
                let image = UIImage(data: data)
                self?.profileImageView.image = image
            }
    }
}
    

Here is the view controller code .

import UIKit
import Combine

class PeopleViewController: UIViewController {
    
    var coordinator: PeopleBaseCoordinator?
    
    
    init(coordinator: PeopleBaseCoordinator) {
        super.init(nibName: nil, bundle: nil)
        self.coordinator = coordinator
        title = "People"
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private let viewModel = ViewModel()
    private var subscribers = Set<AnyCancellable>()
    
    
    private  var activityIndicator = UIActivityIndicatorView(style: .medium)
    
    
    private lazy var tableView: UITableView = {
        let tableview = UITableView()
        tableview.translatesAutoresizingMaskIntoConstraints = false
        tableview.dataSource = self
        tableview.prefetchDataSource = self
        tableview.showsVerticalScrollIndicator = false
        tableview.register(PeopleCell.self, forCellReuseIdentifier: PeopleCell.identifier)
        
        return tableview
    }()
    
   

    override func viewDidLoad() {
        super.viewDidLoad()
        
        activityIndicator.startAnimating()
        setUpUI()
       
        setUpBinding()
        self.activityIndicator.stopAnimating()
     
        // Do any additional setup after loading the view.
    }
    
    
    private func setUpUI() {
        view.backgroundColor = .white
        
        title = "People List "
        
        view.addSubview(activityIndicator)
        view.addSubview(tableView)
       // self.tableView.rowHeight = 100.00
        
        tableView.rowHeight = UITableView.automaticDimension
        tableView.rowHeight = 100
       
        tableView.topAnchor.constraint(equalTo:view.safeAreaLayoutGuide.topAnchor).isActive = true
        tableView.leftAnchor.constraint(equalTo:view.safeAreaLayoutGuide.leftAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo:view.safeAreaLayoutGuide.rightAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
       
        
        
        // Creating constrain for Indecator
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
       
        activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          
    }
    
    private func setUpBinding() {
        viewModel
            .$peoples
            .receive(on : RunLoop.main)
            .sink { [weak self ] _ in
                self?.tableView.reloadData()
            }
            .store(in: &subscribers)
        viewModel.getPeople()
        
    }

}
extension PeopleViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.peoples.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: PeopleCell.identifier, for: indexPath) as? PeopleCell
        else { return UITableViewCell() }
        
        
        let row = indexPath.row
        
    
        let people = viewModel.peoples[row]
        cell.configureCell(firstName: people.firstName, lastName: people.lastName,jobtitle: people.jobtitle)
    
        cell.configureImageCell(row: row, viewModel: viewModel)
        
        return cell
        
    }
  
}
extension PeopleViewController: UITableViewDataSourcePrefetching {
    
    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
        viewModel.getPeople()
    }
    
}

Here is the screenshot . As it not showing the job title property into cell . enter image description here

12
  • I would suggest using the view debugger in Xcode to diagnose what’s going on, rather than reverse engineering the code. Commented Apr 26, 2022 at 15:23
  • Can you explain what the 4 lines with constraints are doing starting at jobTitleLabel.topAnchor.constraint Commented Apr 26, 2022 at 15:24
  • But I see strange constraints in your code, above. Several constraints repeated. Several missing. The “Debug View Hierarchy” button will help you diagnose (the missing ones, at least). It will also help you examine the size and placement of the control that is missing. Commented Apr 26, 2022 at 15:24
  • 1
    Look at job title, for example. You should set top, bottom, leading and trailing. But you’re setting top twice, setting leading twice, and never setting bottom or trailing. If you used the view debugger, it would point out these ambiguous constraints. Commented Apr 26, 2022 at 15:35
  • 2
    You need to make sure you have enough constraints in both horizontal and vertical dimensions, so that auto layout can unambiguously lay out your views by solving your constraint equations. The duplication was redundant but not actually the main issue here Commented Apr 26, 2022 at 15:46

1 Answer 1

0

I think your problem is the height of your containerView containerView.heightAnchor.constraint(equalToConstant:40).isActive = true

I think 40 is to low to show the jobTitleLabel

Sign up to request clarification or add additional context in comments.

2 Comments

I think there are many deeper problems here. Besides, when using autolayout, it’s better to not set the explicit height at all, and use self-sizing cells.
I agree, explicit height is not good.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.