iOS UITableView with Multiple Cell Types With Examples

In this tutorial, we’ll be developing an iOS Application using Swift that has a single iOS UITableView with two different types of UITableViewCells.

Multiple Cells inside a TableView are commonly seen in the Facebook newsfeed application which hosts cells largely grouped into three types – Status Posts, Image Posts and Video Posts.

iOS UITableView with different type of cells

We’ll be creating an application that displays two types of cells. First, that displays country flag and name. Second, that displays population for the country. We’ll be populating the data in the UITableView from a generic array.

Let’s start our XCode and select a Single View Application template. We’ll setup our UI in Main.storyboard using Autolayout as shown below.

  1. Adding a TableView and setting up its constraints. Displaying two prototype cells.ios uitableview multiple cell types autolayout 1
  2. Adding a UIImageView and Label in the first prototype cell followed by setting their constraints.ios uitableview multiple cell types
  3. Setting up the second prototype cell followed by defining the identifiers and class name for each UITableViewCell.ios tableview autolayout
  4. Adding the references of the views in the ViewController and Custom Cells.ios tableview multiple cell types views hook

The code for the ViewController.swift file is given below.


import UIKit
class CustomCountryCell: UITableViewCell{
    @IBOutlet var countryName: UILabel!
    @IBOutlet var countryIcon: UIImageView!
}
class CustomPopulationCell: UITableViewCell{
    @IBOutlet var countryPopulation: UILabel!
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    @IBOutlet var tableView: UITableView!
    var tableData = ["Australia", 24.13, "Canada", 36.29 ,"China", 1379, "India", 1324, "United States of America", 323.1] as [Any]
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tableView.dataSource = self
        tableView.delegate = self
        tableView.tableFooterView = UIView()
        tableView.rowHeight = 60
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let string = self.tableData[indexPath.row] as? String
        {
            let cell:CustomCountryCell = self.tableView.dequeueReusableCell(withIdentifier: "customCountryCell") as! CustomCountryCell
            cell.countryName?.text = string
            cell.countryIcon?.image = UIImage(named:string)
            return cell
        }
        else if let population = self.tableData[indexPath.row] as? Any, population is Double || population is Int {
            let cell:CustomPopulationCell = self.tableView.dequeueReusableCell(withIdentifier: "customPopulationCell") as! CustomPopulationCell
            cell.countryPopulation?.text = "Population is (population) million"
            return cell
        }
        return UITableViewCell()
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tableData.count
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

Following are the notable things present in the ViewController class.

    • We’ve implemented the two protocols present in the UITableView class i.e. UITableViewDelegate and UITableViewDataSource

.

  • tableData is a generic array that holds String, Double and Integer types. The string element is used to set the Image(the image assets have the same name set in the Assets folder) and country name.
  • tableView.tableFooterView = UIView() removes the empty cells after the last populated row in the UITableView.
  • tableView.rowHeight = 60 sets the row height for each UITableViewCell.
  • Cell of the type CustomCountryCell is added in the UITableView if the current element in the tableData is a String.
  • To check whether the current element in the tableData is of the type Double or Integer the following condition is used :
    
    if let population = self.tableData[indexPath.row] as? Any, population is Double || population is Int {
    }
    

    In the above code snippet, the , acts as a where clause. The condition reads as : “if self.tableData[indexPath.row] is a valid element, typecast it to Any and check whether it is of the type Double OR type Int”.

    Note: The above condition can be written in following way too.

    
    else if let population = self.tableData[indexPath.row] as? Double{
                let cell:CustomPopulationCell = self.tableView.dequeueReusableCell(withIdentifier: "customPopulationCell") as! CustomPopulationCell
                cell.countryPopulation?.text = "Population is (population) million"
                return cell
            }
            else if let population = self.tableData[indexPath.row] as? Int{
                let cell:CustomPopulationCell = self.tableView.dequeueReusableCell(withIdentifier: "customPopulationCell") as! CustomPopulationCell
                cell.countryPopulation?.text = "Population is (population) million"
                return cell
            }
    
  • return UITableViewCell() is used to add a default empty cell if none of the conditions match.
  • didSelectRowAt function is used to add the click animation on each TableView row.

The output of the above application in action is given below.
iOS TableView Multiple Cells Apps

This brings an end to this tutorial. A similar implementation for Android using RecyclerView is given here. You can download the iOS TableViewMultipleCellTypes Project from the link below.

Reference: Apple Documentation

By admin

Leave a Reply

%d bloggers like this: