iOS: Table View
A TableView is a type of view that uses rows in a single column to organize data. Nearly all iOS applications, including Contacts, Facebook, Instagram, and others, use it. The UITableView class, which derives from the UIScrollView class, is represented by the tableview instance. The following chapters of this tutorial will cover UIScrollView.
class UITableView : UIScrollView
Tableview is used in iOS applications whenever we need to show a single column with material that scrolls vertically. The tableview allows for the vertical scrolling of many records that are separated into rows for presentation. Every record from the data source is shown in a row within the tableview. For instance, in the contact app, each contact name is shown in a separate tableview row, and clicking on that row retrieves the contact’s details.
The tableview in the settings app is used to display data, as seen in the image below.
The Contact app’s usage of tableview is depicted in the image below.
To organize related rows in a tableview, we can either build sections or display a lengthy list of records in several rows without any parts.
Data is arranged hierarchically in iOS applications by using the tableview in conjunction with the navigation controller. Here, the navigation controller allows us to move between the various hierarchical levels.
The UIScrollView class is inherited by the UITableView class, which controls the tableview’s look. The object of the UITableViewCell class simulates the row in tableview and may be used to show the actual content. Any content from the iOS application can be displayed in the tableview cells by customizing them.
Adding UITableView to interface
Drag the Tableview that appears from your search for it in the object library onto the storyboard to add it.
We must set the tableview’s data source and delegate settings before we can utilize it. The tableview obtains the data to be displayed from the data source object because it is a data-driven object. The data returned by an API request from the database server is stored in the data source object in real-world applications.
In the viewDidLoad method of ViewController, the delegate and data source attributes of the tableview can be set with the following code.
tableView.delegate = self
tableView.datasource = self
TableView Delegate Methods
The following characteristics are defined to be added to the tableview by the tableview delegate methods.
We are able to design the unique tableview section headers and footers.
The custom heights for headers, footers, and rows can all be specified.
Estimate the heights of the headers, footers, and rows.
We are able to provide the method that manages row selections.
SN | Method | Description |
---|---|---|
1 | func tableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath) | The tableview notifies this delegate when it is about to draw a cell for a particular row. |
3 | func tableView(UITableView, willSelectRowAt: IndexPath) -> IndexPath? | The tableview notifies this delegate method when the specified row is about to be selected. |
4 | func tableView(UITableView, didSelectRowAt: IndexPath) | This delegate is notified when the specified row of the tableview is selected. |
5 | func tableView(UITableView, willDeselectRowAt: IndexPath) -> IndexPath? | This delegate is notified when the particular cell is about to be deselected. |
6 | func tableView(UITableView, didDeselectRowAt: IndexPath) | This delegate is notified when the particular row is deselected. |
7 | func tableView(UITableView, viewForHeaderInSection: Int) -> UIView? | This delegate method returns a UIView which represents the header of the tableview. |
8 | func tableView(UITableView, viewForFooterInSection: Int) -> UIView? | This delegate method returns the uiview, which represents the footer of the tableview. |
9 | func tableView(UITableView, willDisplayHeaderView: UIView, forSection: Int) | This delegate method is notified when the tableview is going to display the headerview for the particular section. |
10 | func tableView(UITableView, willDisplayFooterView: UIView, forSection: Int) | This delegate method is notified when the tableview is going to display the footer view for the particular section. |
11 | func tableView(UITableView, heightForRowAt: IndexPath) -> CGFloat | This delegate method returns the height for the row. |
12 | func tableView(UITableView, heightForHeaderInSection: Int) -> CGFloat | This delegate method returns the height of the header of section in the tableview. |
13 | func tableView(UITableView, heightForFooterInSection: Int) -> CGFloat | This delegate method returns the height for the footer of a particular section in the tableview. |
14 | func tableView(UITableView, estimatedHeightForRowAt: IndexPath) -> CGFloat | It asks the delegate for the estimated height of the row in a particular location. |
15 | func tableView(UITableView, estimatedHeightForHeaderInSection: Int) -> CGFloat | It asks the delegate for the estimated height of the header in a particular location. |
16 | func tableView(UITableView, estimatedHeightForFooterInSection: Int) -> CGFloat | It asks the delegate for the estimated height for the footer in the particular section. |
TableView DataSource Methods
SN | Method | Description |
---|---|---|
1 | func tableView(UITableView, numberOfRowsInSection: Int) -> Int | This method returns the number of rows to be displayed in the section of the tableview. |
2 | func numberOfSections(in: UITableView) -> Int | This method returns the number of sections to be displayed in the tableview. |
3 | func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell | This method returns the object of a UITableViewCell, which shows the actual content of a particular row in the tableview. This method inserts the cell for a particular row in the tableview. |
4 | func tableView(UITableView, titleForHeaderInSection: Int) -> String? | This method returns a string representing the title of the header in the section of the tableview. |
5 | func tableView(UITableView, titleForFooterInSection: Int) -> String? | This method returns a string representing the title of the footer in the section of the tableview. |
7 | func tableView(UITableView, canEditRowAt: IndexPath) -> Bool | It asks the DataSource to verify whether the particular row is editable or not. |
8 | func tableView(UITableView, canMoveRowAt: IndexPath) -> Bool | It asks the DataSource to verify whether the particular row can be moved to another location in the tableview. |
9 | func tableView(UITableView, moveRowAt: IndexPath, to: IndexPath) | This method moves the specific row to some other location in the tableview. |
10 | func sectionIndexTitles(for: UITableView) -> [String]? | It returns the array of the string containing the titles for the sections in the tableview. |
If the ViewController implements the UITableViewDatasource protocol, as described in the following code, then two methods must be implemented.
extension ViewController : UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSourceArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "cell text"
return cell
}
}
Example 1
We’ll build a straightforward tableview in this example that lists the top 10 programming languages for 2019. In this example, the interface builder will be created using UITableView, and the data will be set in the tableview using the delegate and datasource methods.
Interface Builder
By include the tableview in the interface builder, we will generate the subsequent view controller in this example. The tableview’s title will also be shown using the label object. This tableview will have a prototype cell added, and this ViewController will have the ViewController.swift class assigned to it.
ViewController.swift
We will create the tableview’s connection outlet in ViewController.swift and add it to the storyboard. In order to display the tableview data, we will also define the delegate and datasource functions.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var dataSourceArr = Array()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
tableView.dataSource = self
dataSourceArr = ["Python","JavaScript","Java","Swift","GoLang","C#","C++","Scala"]
}
}
extension ViewController : UITableViewDelegate{
}
extension ViewController : UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSourceArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = dataSourceArr[indexPath.row]
cell.textLabel?.textAlignment = .center
return cell
}
}
Output
Example: Handling multiple sections in the tableview
In this example, we will construct several tableview sections and specify the row content and number that vary based on the specific section.
Interface Builder
We must add a tableview and a prototype cell for the tableview before we can develop the interface builder for this example. With a prototype cell, the interface builder appears like the image below.
ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController: UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return 2
}
else if section == 1{
return 3
}
else if section == 2{
return 4
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(indexPath.section == 0){
cell.textLabel?.text = "Row in section 1"
}
else if(indexPath.section == 1){
cell.textLabel?.text = "Row in section 2"
}
else if(indexPath.section == 2){
cell.textLabel?.text = "Row in section 3"
}
return cell
}
}
extension ViewController : UITableViewDelegate{
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Section " + (section+1).description
}
}
Example 2: Customizing Table View cell
The tableview cell will be customized in this example by being assigned to a class and having the outlets of the cell objects in that class created. Since we can’t always satisfy our requirements by just modifying the cell’s label text, most iOS applications require us to customize the tableview class.
The product list view that appears in the e-commerce application is simulated in this example.
Interface Builder
We must add the tableview and prototype cell to the view controller in order to develop the interface builder for this example. We will add an uiview to the content view prototype cell, to which we will add UILabel and UIImageView objects. The example storyboard is displayed in the following image.
MyTableViewCell.swift
The UITableViewCell class, which is assigned to the tableview prototype cell, is inherited by MyTableViewCell. We can instantiate the picture view and label objects in this class.
import UIKit
class MyTableViewCell: UITableViewCell {
@IBOutlet weak var titleImg: UIImageView!
@IBOutlet weak var titleLbl: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
var imgArr = ["Product1","Product2","Product3","Product4","Product5","Product6","Product7","Product8"]
var lblTextArr = ["Powerbanks","Storage Devices","LED Bulbs","Laptop Bags","Keyboards","Routers","Shoes"]
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController : UITableViewDataSource{
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return imgArr.count - 1
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
cell.titleImg?.image = UIImage(named: imgArr[indexPath.row])
cell.titleLbl.text = lblTextArr[indexPath.row]
return cell
}
}
extension UIViewController : UITableViewDelegate{
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
}