In this tutorial, we’ll be developing an iOS Application that contains a custom TableView with cells having a custom layout inclusive of images, label and a checkmark. Let’s create a new SingleView Application project and get on with it.
iOS Custom TableView Project Structure
The project consists of a ViewController.swift
class file which would hold the class for CustomTableViewCells too. Also, the images that we would be displaying shall be present in the Assets folder.
Building Storyboards for iOS TableView
- Adding a TableView and setting its constraints.
- Adding a TableViewCell and an ImageView in the cell and setting its constraints.
- Adding a label between the ImageView and the AccessoryType – checkmark and setting its constraints.
- The
ViewController.swift
would contain another class CustomCell that implements the UITableViewCell protocol as shown below.
123456789101112131415import UIKitclass CustomCell : UITableViewCell{}class ViewController: UIViewController {override func viewDidLoad() {super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.}override func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()// Dispose of any resources that can be recreated.}} - Let’s link these classes with the storyboard.
iOS Custom TableView Example Code
The code for the ViewController.swift
file is given below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import UIKit class CustomCell : UITableViewCell{ @IBOutlet var myImage: UIImageView! @IBOutlet var myText: UILabel! } class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { @IBOutlet var tableView: UITableView! var labelData = ["Australia", "Brazil", "Canada","China","Germany","India","Malaysia", "Pakistan", "Russia", "South Africa", "United States of America"] var imageData = ["Australia", "Brazil", "Canada","China","Germany","India","Malaysia", "Pakistan", "Russia", "SouthAfrica", "UnitedStatesofAmerica"] 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() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell:CustomCell = self.tableView.dequeueReusableCell(withIdentifier: "customCell") as! CustomCell cell.myText?.text = self.labelData[indexPath.row] cell.myImage?.image = UIImage(named:self.imageData[indexPath.row]) return cell } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return labelData.count } func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) if let cell = tableView.cellForRow(at: indexPath as IndexPath) { if cell.accessoryType == .checkmark{ cell.accessoryType = .none } else{ cell.accessoryType = .checkmark } } } } |
In the above code, we set the label and image from the labelData and imageData arrays respectively.
To check/uncheck a cell, we check the accessoryType
attribute on the cell. If it’s equal to checkmark we toggle it to none and vice versa.
The output for the above application in action is given below.
In case we want to allow single choice selection only we can use the below code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import UIKit class CustomCell : UITableViewCell{ @IBOutlet var myImage: UIImageView! @IBOutlet var myText: UILabel! //For single choice selection required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! selectionStyle = .none } } class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { @IBOutlet var tableView: UITableView! var labelData = ["Australia", "Brazil", "Canada","China","Germany","India","Malaysia", "Pakistan", "Russia", "South Africa", "United States of America"] var imageData = ["Australia", "Brazil", "Canada","China","Germany","India","Malaysia", "Pakistan", "Russia", "SouthAfrica", "UnitedStatesofAmerica"] 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() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell:CustomCell = self.tableView.dequeueReusableCell(withIdentifier: "customCell") as! CustomCell cell.myText?.text = self.labelData[indexPath.row] cell.myImage?.image = UIImage(named:self.imageData[indexPath.row]) return cell } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return labelData.count } func numberOfSections(in tableView: UITableView) -> Int { return 1 } // func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // tableView.deselectRow(at: indexPath, animated: true) // // if let cell = tableView.cellForRow(at: indexPath as IndexPath) { // if cell.accessoryType == .checkmark{ // cell.accessoryType = .none // } // else{ // cell.accessoryType = .checkmark // } // } // // } //For single choice selection func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none } } |
In the above code, we override the functions didSelectRowAt
as well as didDeselectRowAt
to allow single choice selection. We can’t use tableView.deselectRow(at: indexPath, animated: true)
to animate the selection anymore since that method is already being overridden. Hence we set the selectionStyle in the customCell as none:
1 2 3 4 5 6 |
required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! selectionStyle = .none } |
The output of the above implementation is given below:
This brings an end to this tutorial. You can download the final iOS CustomTableViewWithImagesAndCheckMarks Project from the link below.
Reference: iOS Table View