Home > OS >  How to add UILabels to UITableVIew programmatically?
How to add UILabels to UITableVIew programmatically?

Time:09-04

I am relatively new to UIKit with Swift. Currently, I am trying to make a simple UITableView containing a few UILabels for each cell (purely programmatically), although I have been having a lot of trouble trying to do this. My code is below:

import UIKit

class SettingsVC: UIViewController {
    
    var settingsTableView = UITableView(frame: .zero, style: .insetGrouped)

    override func viewDidLoad() {
        super.viewDidLoad()
        createTableView()
    }
    
    func createTableView() {
        view.addSubview(settingsTableView)
        setTableViewDelegates()
        
        settingsTableView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            settingsTableView.topAnchor.constraint(equalTo: view.topAnchor),
            settingsTableView.leftAnchor.constraint(equalTo: view.leftAnchor),
            settingsTableView.rightAnchor.constraint(equalTo: view.rightAnchor),
            settingsTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])
    }
    
    func setTableViewDelegates() {
        settingsTableView.delegate = self
        settingsTableView.dataSource = self
    }
}

extension SettingsVC: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 4
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return UITableViewCell()
    }
}

This is currently what shows up in the Simulator.

This is what I would like to see.

How can I go about changing my preexisting code to get the end result I'm seeking? I have a feeling it has something to do about my delegate or data source, but no matter what I try, I seem to always get lost. Any help would be greatly appreciated.

CodePudding user response:

You need to make a custom cell class first

class CustomTableViewCell: UITableViewCell

make sure to give your custom cell the reuseIdentifier. For example,

class CustomTableViewCell: UITableViewCell { 
    static let reuseIdentifier: "CustomTableViewCell"  
}

and inside that cell class, configure your desired label just like you did with settingsTableView in SettingsVC

and return your CustomTableViewCell in the cellForRowAt function in SettingsVC

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.reuseIdentifier) as? CustomTableViewCell else {
        print("Cannot find CustomTableViewCell")
        return UITableViewCell()
    }

    return cell
}

CodePudding user response:

You're correct about missing the data source. you will have to declare your data source. I have refactored a bit of your code as below

import UIKit

class SettingsVC: UIViewController {
    
    lazy var settingsTableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .insetGrouped)
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.delegate = self
        tableView.dataSource = self
        return tableView
    }()
    
    //cell identifier
    let cellIdentifier = "CellName"
    
    //declare a datasource with your data
    let myDataSource = ["Hello", "There", "My", "Friend"]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
    }
    
    func setupView() {
        view.addSubview(settingsTableView)
        NSLayoutConstraint.activate([
            settingsTableView.topAnchor.constraint(equalTo: view.topAnchor),
            settingsTableView.leftAnchor.constraint(equalTo: view.leftAnchor),
            settingsTableView.rightAnchor.constraint(equalTo: view.rightAnchor),
            settingsTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])
    }
}


extension SettingsVC: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myDataSource.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // This is how UITableView works:
        // when the table becomes very long (let's say millions of cells)
        // then the table will first allocate 4-5 cells to fill the iPhone's screen
        // depend on the device's screen size, the number of cells will be different.
        // as long as users scroll the table view down, the table view will re-use existing cells and update the values accordingly, there is no new memory allocated
        // So the cell can be re-usable therefore you should call this func below to reduce memory warning issue
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
        guard let myCell = cell else {
            return UITableViewCell()
        }
        let myText = myDataSource[indexPath.row]
        myCell.textLabel?.text = myText
        return myCell
    }
}
  • Related