iOS & Swift Tutorial: UITableViewController

This tutorial shows how to:

Requirements

For this tutorial you need basic programming skills and know how to use Xcode. You should know everything that is in the “How to develop an iPhone app” iOS Tutorial. To develop iOS apps for the iPhone/iPad using the latest Xcode 9, you’ll need a Mac running the at least Mac OS X 10.12 Sierra.

Creating an example project

  1. Run Xcode and create a new project with File » New » Project ⌘⇧N. Select iOS » Application » Single View Application:

    File » New » Project » iOS » Application » Single View Application
  2. Name the app “TableExample”.
    Choose Swift as Language, select iPhone for Devices.

    New project settings

  3. Delete the controller class ViewController.swift that was created automatically:

    Delete ViewController.swift
  4. Open Main.storyboard, select the controller that was created automatically in the Outline and delete it with Edit » Delete so that the storyboard is completely empty:

    Delete default controller in storybord

Configure table contents using the Storyboard

  1. Drag in a new Table View Controller from the Object Library:

    Add a Table View Controller in the Storyboard
  2. Configure the controller as Initial View Controller:

    Initial View Controller
  3. Shift-Click on the table to see all objects at that position and select Table View:

    Select Table View With Shift+Click
  4. In the Attributes Inspector configure Static Cells for Content to configure the Table View cells in the storyboard instead of writing code to provide the data. Set the Style of the Table View to Grouped:

    Table View: Static Cells + Style Grouped
  5. Show the Document Outline and familiarize yourself with the object structure. The Table View Controller manages its Table View consisting of a single Table View Cell row and an empty Content View in the cell:

    Outline View for Table View Controller
  6. Select the section using the outline or with Shift + Click. Set Table Demos as Header text:

    Section Header
  7. Select the first cell and configure Basic as Style for all cells. A Basic Cell has one Label by default:

    Cell Styles
  8. Configure Basic as Style for the second cell as well and delete the third cell. Configure the label texts like this:

    Table Contents

  9. Run the app with ⌘R.

Creating a Storyboard Segue

  1. Select the Table View Controller and use Editor » Embed In » Navigation Controller to embed the controller into a UINavigationController that manages a navigation stack:

    Embed In Navigation Controller

  2. Drag in another Table View Controller from the Object Library behind the existing controller.

  3. Drag a connection from the first cell of the controller to the second controller with Ctrl pressed down / with the right mouse key. Create a Selection Segue » show:

    Create Segue
  4. Select the segue to check that it connects the cell to the other Table View Controller:

    Segue Connection

Provide section and row content programmatically

  1. Create a new source code file:

    New File
  2. Choose Cocoa Touch Class for iOS:

    New iOS Cocoa Touch Class
  3. Create a subclass of UITableViewController in Swift and name it FruitsTableViewController:

    New Table View Controller Class
  4. In the FruitsTableViewController class, customize the numberOfSectionsInTableView and tableView:numberOfRowsInSection: methods from the UITableViewDataSource protocol to return a fixed number of sections and rows and remove the #warning comments:

    Section and Row Counts in UITableViewDataSource
  5. Open the storyboard and set FruitsTableViewController as class for the second Table View Controller:

    Tableviewcontroller Class
  6. Select the Prototype cell, set Basic as Style and configure LabelCell as Identifier. The identifier is used in the controller implementation to create cells according to the prototype from the Storyboard:

    Cell Reuse Identifier
  7. Uncomment the tableView:cellForRowAtIndexPath: method and customize it to create cells according to the Prototype cell and configure the cell text to show the section and row numbers:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)
    
        cell.textLabel?.text = "Section \(indexPath.section) Row \(indexPath.row)"
    
        return cell
    }
  8. Overwrite the tableView:titleForHeaderInSection: method using the Xcode code completion:

    Overwrite tableView:titleForHeaderInSection: method

    Implement the method to return a title according to the section number:

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Section \(section)"
    }
  9. Remove the remaining code in the class, this should be the code in the class:

    import UIKit
    
    class FruitsTableViewController: UITableViewController {
    
        // MARK: - Table view data source
    
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 3
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 5
        }
    
      override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
         return "Section \(section)"
      }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)
    
            cell.textLabel?.text = "Section \(indexPath.section) Row \(indexPath.row)"
    
            return cell
        }
                   
    }
  10. Run the app with ⌘R:

    Table showing the section and row

Show data from a Swift Array

  1. Customize the FruitsTableViewController to use data from a Swift Array:

    class FruitsTableViewController: UITableViewController {
    
        var fruits = ["Apple", "Apricot", "Banana", "Blueberry", "Cantaloupe", "Cherry",
            "Clementine", "Coconut", "Cranberry", "Fig", "Grape", "Grapefruit",
            "Kiwi fruit", "Lemon", "Lime", "Lychee", "Mandarine", "Mango", 
            "Melon", "Nectarine", "Olive", "Orange", "Papaya", "Peach", 
            "Pear", "Pineapple", "Raspberry", "Strawberry"]
        
        // MARK: - UITableViewDataSource
    
        override func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return fruits.count
        }
        
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)
            
            cell.textLabel?.text = fruits[indexPath.row]
            
            return cell
        }
        
    }

    Hint: You can also remove the numberOfSections method - by default tables have one section.

    Hint: The “// MARK: ” comment groups the methods, for example when choosing a method from the Jump Bar:

    Jumpbar Method Groups

  2. Run the app with ⌘R:

    Table View with data from Swift Array

Configure cells using cell styles

  1. There are four different types of cell styles that have views out of the box - Basic, Left/Right Detail and Subtitle:

    UITableViewController Cell Styles

    For the FruitTableViewController in the storyboard, select the first cell and set the style Subtitle:

    Cell Styles
  2. Download fruit-images.zip and add the images to the Assets.xcassets in your project:

    Fruits Assets

  3. Extend the implementation of tableView(cellForRowAt:) in FruitsTableViewController to show a detail text and an image (all cells have an optional imageView that gets created as soon as the imageView property is accessed):

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)
    
        let fruitName = fruits[indexPath.row]
    cell.textLabel?.text = fruitName
    cell.detailTextLabel?.text = "Delicious!"
    cell.imageView?.image = UIImage(named: fruitName)
        
        return cell
    }
  4. Run the app and check that the table looks like this:

    Fruits Images Cell

Example code

TableExample

More UITableViewController tutorials

More information

Ralf Ebert Ralf Ebert is an independent software developer and trainer for Mac OS X and iOS. He makes the Page Layers and Straight ahead apps and conducts iOS trainings in Germany since 2009.