← Back to Blog

Swift TableView Basics: How to Create and Populate Tables

coding
mobile
tutorial

By Kevin Hou

5 minute read

Project Objectives

I was instructed to integrate HealthKit information — specifically pulling steps data — into Breathometer's upcoming app. I'm realitively new to Swift having only started a month ago, so this project was a way for me to get more familiar with the language and IDE. My task was to pull the data from HealhtKit then populate a table within a page of the app. This data could then be used for visualizations, analysis, etc. Here are my main learning goals for this project:

Setting Up the Table

Create a table view property

1@IBOutlet weak var tableView: UITableView! // Connect to the storyboard element 2

Initialize the class and connect it to the storyboard.

1class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { ... } 2

Setup different UITableView properties

1// Imperative 2func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 3 return 0 4} 5 6// Imperative 7func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 8 return UITableViewCell() 9} 10 11func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 12 // Triggered when you select the row at indexPath 13} 14

Connect dataSource and delegate

You must also link the table view dataSource and delegate to the view controller like so: swift table views

Register Cell Class

In the view controller/tableviewdelegate/datasource class, you must register the class for the table view:

1override func viewDidLoad() { 2 super.viewDidLoad() 3 4 self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell") 5// tableView.setup(scrollable: false) // Turn off scrolling 6} 7

Adding Data to Display

First step is to declare the data. In this case we’re going to use dummy data:

1var items: [String] = ["Hello", "World", "Swift"] 2

Using this data, we can now set the number of rows in our table view by calling the function:

1func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 2 return items.count 3} 4

Create the Cell

1func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 2 var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell 3 4 cell.textLabel?.text = self.items[indexPath.row] 5 6 return cell 7} 8

Handling Cell Selection

1func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 2 println("You selected cell #\(indexPath.row)!") 3} 4

Final code

1class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 2 @IBOutlet 3 var tableView: UITableView 4 var items: [String] = ["We", "Heart", "Swift"] 5 6 override func viewDidLoad() { 7 super.viewDidLoad() 8 9 self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell") 10 } 11 12 13 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 14 return self.items.count; 15 } 16 17 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 18 var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell 19 20 cell.textLabel?.text = self.items[indexPath.row] 21 22 return cell 23 } 24 25 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 26 println("You selected cell #\(indexPath.row)!") 27 } 28} 29

Custom Cell Layout

By default, all table view cells have the text label and detail label values. To create a custom cell with more than just those two labels, follow these steps:

Drag a Table View Cell onto your UITableView. This will automatically generate a cell labeled “Prototype” that contains a nested content view. Treat this content view as any other view and drag UI elements like text fields, images, etc. onto the content view.

Now, create a new Swift file for the UITableViewCell class to connect your Table View Cell to some code. Initialize the class like so:

1class StepsCell: UITableViewCell { 2 // IB Outlets go here: 3 4 override func awakeFromNib() { 5 super.awakeFromNib() 6 // Initialization code 7 } 8 9 override func setSelected(selected: Bool, animated: Bool) { 10 super.setSelected(selected, animated: animated) 11 12 // Configure the view for the selected state 13 } 14} 15

Hook up the UI elements in the content view with IBOutlets in your UITableViewCell class. It’s identical to how you would do this for any other view controller. You can add constraints, stack views, etc. Just treat the content view as you would a blank view controller.

Now to access those UI elements in your main Table View Controller, you must use the “dequeueReusableCellWithIdentifier” command. Dequeue basically describes the manner in which data loads and unloads. If you imagine the scrolling items as a wheel, as the topmost item disappears, it reappears on the bottom. The table view is endlessly recycling the same x number of cells. This is a good approach for memory management especially when dealing with 100+ cells. Once you’ve stored the cell, you can then modify the various UI elements and return the cell to populate the table view.

1func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 2 var cell = self.tableView.dequeueReusableCellWithIdentifier("StepsCell")! as! StepsCell // Same identifier as class name 3 cell.dateLabel.text = "January \(indexPath)" 4 cell.textLabel?.text = String(indexPath) 5 return cell 6} 7

Other Helpful Topics

For populating table views with data from asynchronous requests, it can be helpful to reload your table view once you know all your data is complete

1// Reload in main queue 2dispatch_async(dispatch_get_main_queue(), { () -> Void in 3 self.tableView.reloadData() // Reload 4}) 5

Tutorial from: https://www.weheartswift.com/how-to-make-a-simple-table-view-with-ios-8-and-swift