Custom UITableViewCell programmatically using Swift Custom UITableViewCell programmatically using Swift ios ios

Custom UITableViewCell programmatically using Swift


Let's make a few assumptions:

You have an iOS8 project with a Storyboard that contains a single UITableViewController. Its tableView has a unique prototype UITableViewCell with custom style and identifier: "cell".

The UITableViewController will be linked to Class TableViewController, the cell will be linked to Class CustomTableViewCell.

You will then be able to set the following code (updated for Swift 2):

CustomTableViewCell.swift:

import UIKitclass CustomTableViewCell: UITableViewCell {    let imgUser = UIImageView()    let labUserName = UILabel()    let labMessage = UILabel()    let labTime = UILabel()    override func awakeFromNib() {        super.awakeFromNib()        imgUser.backgroundColor = UIColor.blueColor()        imgUser.translatesAutoresizingMaskIntoConstraints = false        labUserName.translatesAutoresizingMaskIntoConstraints = false        labMessage.translatesAutoresizingMaskIntoConstraints = false        labTime.translatesAutoresizingMaskIntoConstraints = false        contentView.addSubview(imgUser)        contentView.addSubview(labUserName)        contentView.addSubview(labMessage)        contentView.addSubview(labTime)        let viewsDict = [            "image": imgUser,            "username": labUserName,            "message": labMessage,            "labTime": labTime,        ]        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[image(10)]", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[labTime]-|", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[username]-[message]-|", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[username]-[image(10)]-|", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[message]-[labTime]-|", options: [], metrics: nil, views: viewsDict))    }}

TableViewController.swift:

import UIKitclass TableViewController: UITableViewController {    override func viewDidLoad() {        super.viewDidLoad()        //Auto-set the UITableViewCells height (requires iOS8+)        tableView.rowHeight = UITableViewAutomaticDimension        tableView.estimatedRowHeight = 44    }    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {        return 1    }    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        return 100    }    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell        cell.labUserName.text = "Name"        cell.labMessage.text = "Message \(indexPath.row)"        cell.labTime.text = NSDateFormatter.localizedStringFromDate(NSDate(), dateStyle: .ShortStyle, timeStyle: .ShortStyle)        return cell    }}

You will expect a display like this (iPhone landscape):enter image description here


This is the update for swift 3 of the answer Imanou Petit.

CustomTableViewCell.swift:

import Foundationimport UIKitclass CustomTableViewCell: UITableViewCell {    let imgUser = UIImageView()    let labUerName = UILabel()    let labMessage = UILabel()    let labTime = UILabel()    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {        super.init(style: style, reuseIdentifier: reuseIdentifier)        imgUser.backgroundColor = UIColor.blue        imgUser.translatesAutoresizingMaskIntoConstraints = false        labUerName.translatesAutoresizingMaskIntoConstraints = false        labMessage.translatesAutoresizingMaskIntoConstraints = false        labTime.translatesAutoresizingMaskIntoConstraints = false        contentView.addSubview(imgUser)        contentView.addSubview(labUerName)        contentView.addSubview(labMessage)        contentView.addSubview(labTime)        let viewsDict = [            "image" : imgUser,            "username" : labUerName,            "message" : labMessage,            "labTime" : labTime,            ] as [String : Any]        contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-[image(10)]", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[labTime]-|", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-[username]-[message]-|", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[username]-[image(10)]-|", options: [], metrics: nil, views: viewsDict))        contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-[message]-[labTime]-|", options: [], metrics: nil, views: viewsDict))    }    required init?(coder aDecoder: NSCoder) {        fatalError("init(coder:) has not been implemented")    }}

Settigns.swift:

import Foundationimport UIKitclass Settings: UIViewController, UITableViewDelegate, UITableViewDataSource {    private var myTableView: UITableView!    private let sections: NSArray = ["fruit", "vegitable"]    //Profile    network    audio Codecs    private let fruit: NSArray = ["apple", "orange", "banana", "strawberry", "lemon"]    private let vegitable: NSArray = ["carrots", "avocado", "potato", "onion"]    override func viewDidLoad() {        super.viewDidLoad()        // get width and height of View        let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height        let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.size.height        let displayWidth: CGFloat = self.view.frame.width        let displayHeight: CGFloat = self.view.frame.height        myTableView = UITableView(frame: CGRect(x: 0, y: barHeight+navigationBarHeight, width: displayWidth, height: displayHeight - (barHeight+navigationBarHeight)))        myTableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "cell")         // register cell name        myTableView.dataSource = self        myTableView.delegate = self        //Auto-set the UITableViewCells height (requires iOS8+)        myTableView.rowHeight = UITableViewAutomaticDimension        myTableView.estimatedRowHeight = 44        self.view.addSubview(myTableView)    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()    }    // return the number of sections    func numberOfSections(in tableView: UITableView) -> Int{        return sections.count    }    // return the title of sections    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {        return sections[section] as? String    }    // called when the cell is selected.    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {        print("Num: \(indexPath.row)")        if indexPath.section == 0 {            print("Value: \(fruit[indexPath.row])")        } else if indexPath.section == 1 {            print("Value: \(vegitable[indexPath.row])")        }    }    // return the number of cells each section.    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        if section == 0 {            return fruit.count        } else if section == 1 {            return vegitable.count        } else {            return 0        }    }    // return cells    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell        if indexPath.section == 0 {            cell.labUerName.text = "\(fruit[indexPath.row])"            cell.labMessage.text = "Message \(indexPath.row)"            cell.labTime.text = DateFormatter.localizedString(from: NSDate() as Date, dateStyle: .short, timeStyle: .short)        } else if indexPath.section == 1 {            cell.labUerName.text = "\(vegitable[indexPath.row])"            cell.labMessage.text = "Message \(indexPath.row)"            cell.labTime.text = DateFormatter.localizedString(from: NSDate() as Date, dateStyle: .short, timeStyle: .short)        }        return cell    }}

Screen Shot


In Swift 5.

The custom UITableViewCell:

import UIKitclass CourseCell: UITableViewCell {    let courseName = UILabel()        override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {        super.init(style: style, reuseIdentifier: reuseIdentifier)                // Set any attributes of your UI components here.        courseName.translatesAutoresizingMaskIntoConstraints = false        courseName.font = UIFont.systemFont(ofSize: 20)                // Add the UI components        contentView.addSubview(courseName)                NSLayoutConstraint.activate([            courseName.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20),            courseName.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -20),            courseName.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20),            courseName.heightAnchor.constraint(equalToConstant: 50)        ])    }        required init?(coder: NSCoder) {        fatalError("init(coder:) has not been implemented")    }}

The UITableViewController:

import UIKitclass CourseTableViewController: UITableViewController {    private var data: [Int] = [1]        override func viewDidLoad() {        super.viewDidLoad()        // You must register the cell with a reuse identifier        tableView.register(CourseCell.self, forCellReuseIdentifier: "courseCell")        // Change the row height if you want        tableView.rowHeight = 150        // This will remove any empty cells that are below your data filled cells        tableView.tableFooterView = UIView()    }    // MARK: - Table view data source    override func numberOfSections(in tableView: UITableView) -> Int {        return 1    }    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {                return data.count    }    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        let cell = tableView.dequeueReusableCell(withIdentifier: "courseCell", for: indexPath) as! CourseCell        cell.courseName.text = "Course name"        return cell    }     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {        tableView.deselectRow(at: indexPath, animated: true)    }}