Home > Back-end >  Creating custom table View with Cell properties programmatically
Creating custom table View with Cell properties programmatically

Time:04-27

I am new to swift . I am trying to create table view and cell programmatically. I want to display the three label properties one below to another . I added the content view with respective label properties . I have set the row height but when I run the app is overlapping.

Here is the my Table view code with view controller .

class RoomViewController: UIViewController {

    var coordinator: RoomBaseCoordinator?
    
    init(coordinator: RoomBaseCoordinator) {
        super.init(nibName: nil, bundle: nil)
        self.coordinator = coordinator
        title = "People"
    }
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private let roomviewModel = RoomViewModel()
    private var subscribers = Set<AnyCancellable>()
    
    
    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(RoomCellTableViewCell.self, forCellReuseIdentifier: RoomCellTableViewCell.identifier)
        
        return tableview
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        activityIndicator.startAnimating()
        setUpUI()
      
        setUpBinding()
        self.activityIndicator.stopAnimating()
     
    }
    private func setUpUI() {
        view.backgroundColor = .white
        
        title = "Room List "
        view.addSubview(tableView)
        tableView.rowHeight = 100
        
        // create constraints
        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
        tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
      
        
        // Creating constrain for Indecator
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activityIndicator)
        activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
          
    }
    private func setUpBinding() {
        roomviewModel
            .$rooms
            .receive(on : RunLoop.main)
            .sink { [weak self ] _ in
                self?.tableView.reloadData()
            }
            .store(in: &subscribers)
        roomviewModel.getRoom()
        
    }

}

extension RoomViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return roomviewModel.rooms.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: RoomCellTableViewCell.identifier, for: indexPath) as? RoomCellTableViewCell
        else { return UITableViewCell() }
        
        
        let row = indexPath.row
        let room = roomviewModel.rooms[row]
        cell.configureCell(createdAt: room.createdAt, IsOccupied: room.isOccupied, maxOccupancy: String(room.maxOccupancy), id: room.id)
        return cell
        
    }
}
extension RoomViewController: UITableViewDataSourcePrefetching {
    
    func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
        roomviewModel.getRoom()
    }
    
}

Here is the cell .

class RoomCellTableViewCell: UITableViewCell {

    static let identifier = "RoomCell"
    
 
    
    private lazy var createdAtLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.boldSystemFont(ofSize: 15)
        label.numberOfLines = 0
        label.textAlignment = .left
        return label
    }()
    
    private lazy var IsOccupiedLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.boldSystemFont(ofSize: 15)
        label.numberOfLines = 0
        //label.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1)
        label.textAlignment = .left
        return label
    }()
    
    private lazy var maxOccupancyLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.boldSystemFont(ofSize: 15)
        label.numberOfLines = 0
        label.textAlignment = .left
        return label
    }()
    
    private lazy var idLabel: UILabel = {
        let label = UILabel()
        label.translatesAutoresizingMaskIntoConstraints = false
        label.font = UIFont.boldSystemFont(ofSize: 15)
        label.numberOfLines = 0
        label.textAlignment = .left
        return label
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
       
      // self.contentView.addSubview(containerView)
        contentView.addSubview(createdAtLabel)
        contentView.addSubview(IsOccupiedLabel)
        contentView.addSubview(maxOccupancyLabel)
      
        
        createdAtLabel.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
        createdAtLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor, constant:10).isActive = true
        createdAtLabel.widthAnchor.constraint(equalToConstant:50).isActive = true
        createdAtLabel.heightAnchor.constraint(equalToConstant:50).isActive = true
        
        contentView.centerYAnchor.constraint(equalTo:self.contentView.centerYAnchor).isActive = true
        contentView.leadingAnchor.constraint(equalTo:self.createdAtLabel.trailingAnchor, constant:10).isActive = true
        contentView.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor, constant:-10).isActive = true
        contentView.heightAnchor.constraint(equalToConstant:50).isActive = true
        
        IsOccupiedLabel.topAnchor.constraint(equalTo:self.contentView.topAnchor).isActive = true
        IsOccupiedLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor).isActive = true
        IsOccupiedLabel.trailingAnchor.constraint(equalTo:self.contentView.trailingAnchor).isActive = true
        
        maxOccupancyLabel.topAnchor.constraint(equalTo:self.IsOccupiedLabel.bottomAnchor).isActive = true
        maxOccupancyLabel.leadingAnchor.constraint(equalTo:self.contentView.leadingAnchor).isActive = true
        maxOccupancyLabel.topAnchor.constraint(equalTo:self.IsOccupiedLabel.bottomAnchor).isActive = true
        
    }
    
    required init?(coder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }
    
    func configureCell(createdAt: String, IsOccupied: Bool, maxOccupancy: String, id : String ) {
        createdAtLabel.text = "CreatedAt :\(createdAt)"
        IsOccupiedLabel.text = "IsOccupied : \(IsOccupied)"
        maxOccupancyLabel.text = "MaxOccupancy : \(maxOccupancy)"
        idLabel.text = "Id : \(id)"
        
        }
}

Here is the result .

enter image description here

CodePudding user response:

In setUpUI() method of your RoomViewController class, set tableView's rowHeight to UITableView.automaticDimension and estimatedRowHeight to 100.

import UIKit

class RoomViewController: UIViewController {
    
    private func setUpUI() {
        
        view.backgroundColor = .white
        
        title = "Room List "
        view.addSubview(tableView)

        tableView.estimatedRowHeight = 100
        tableView.rowHeight = UITableView.automaticDimension
        
        // create constraints
        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
        tableView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        
        
        // Creating constrain for Indecator
        activityIndicator.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(activityIndicator)
        activityIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        activityIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        
    }
}

And add UIStackView in the RoomCellTableViewCell class as bellow:

import UIKit

class RoomCellTableViewCell: UITableViewCell {
    
    private var stackView: UIStackView = {
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.distribution = .fill
        stackView.alignment = .fill
        stackView.spacing = 8
        stackView.translatesAutoresizingMaskIntoConstraints = false
        return stackView
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        addSubview(stackView)
        
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: topAnchor),
            stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
            stackView.leftAnchor.constraint(equalTo: leftAnchor),
            stackView.rightAnchor.constraint(equalTo: rightAnchor)
        ])
        
        stackView.addArrangedSubview(createdAtLabel)
        stackView.addArrangedSubview(isOccupiedLabel)
        stackView.addArrangedSubview(maxOccupancyLabel)
        // stackView.addArrangedSubview(idLabel)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
  • Related