Prepared and tested with Xcode 9.3 and Swift 4.1 (2018-04-01)
In this tutorial we cover the following topics
- General information
- Customizing table view cells with nib files
- Customizing table view cells with storyboard
- Customizing table view programmatically
- Todo (id=ios:tab-view-custom-program): Prepare "Customizing table view programmatically"
General information
There are three basic approaches to create our own table view cells
- one that involves loading a cell from a nib file,
- a second that is similar, but loads the cell from a storyboard,
- and a third that involves adding subviews to UITableViewCell programmatically when creating the cell.
Customizing table view cells with nib files
- Step 1: create a new project
Create a new project- Select File | New | Project...
- Select Single View Application on the template selection sheet.
- As the product name enter
Swift iOS Table View Custom Cell Nib
- Set the Language to Swift. Because we will not use tests in this tutorial, you can leave both test check boxes unchecked as well as make sure the check box labeled Use Core Data is also unchecked
- Step 2: create a new class
- In the Project Navigator, right-click the iOS Table View Custom Cell Nib group and select New File....
- Choose Cocoa Touch Class from the iOS Source section in the template dialog and then press Next
- Name the new class
PeakInfoCell
, make it a subclass ofUITableViewCell
. - Make sure that the Also create XIB file check box is checked this time
- Press Next and then press Create to save the files
- Step 3: add a new code and a table view
- Single-click
PeakInfoCell.swift
and add/modify the following code
12345678910111213141516171819202122232425262728293031323334import UIKitclass PeakInfoCell: UITableViewCell {var name = ""var height = ""@IBOutlet weak var labelName: UILabel!@IBOutlet weak var labelHeight: 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}func setName(name: String) {if !self.name.elementsEqual(name) {self.name = nameself.labelName.text = self.name}}func setHeight(height: String) {if !self.height.elementsEqual(height) {self.height = heightself.labelHeight.text = self.height}}} - Single-click
ViewController.swift
and add/modify the following code
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253import UIKit// Trick to get static variable in Swiftstruct staticVariable { static let PeakInfoCellIdentifier = "PeakInfoCellIdentifier" }class ViewController: UIViewController, UITableViewDataSource {var eightThousandersPeaks = [String]()var eightThousandersPeaksHeight = [String]()@IBOutlet weak var tableView: UITableView!override func viewDidLoad() {super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.eightThousandersPeaks += ["Mount Everest", "K2", "Kangchenjunga","Lhotse","Makalu", "Cho Oyu","Dhaulagiri","Manaslu", "Nanga Parbat","Annapurna I", "Gasherbrum I", "Broad Peak","Gasherbrum II", "Shishapangma"]eightThousandersPeaksHeight += ["8850", "8611", "8586","8516", "8463", "8201","8167", "8156", "8126","8091", "8068", "8047","8035", "8013"]let nib = UINib(nibName: "PeakInfoCell", bundle: nil)tableView.register(nib, forCellReuseIdentifier: staticVariable.PeakInfoCellIdentifier)}override func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()// Dispose of any resources that can be recreated.}func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return eightThousandersPeaks.count;}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {var cell:PeakInfoCell? = (tableView.dequeueReusableCell(withIdentifier: staticVariable.PeakInfoCellIdentifier) as? PeakInfoCell)if cell == nil {cell = (UITableViewCell(style: .subtitle, reuseIdentifier: staticVariable.PeakInfoCellIdentifier) as? PeakInfoCell)}cell?.setName(name: eightThousandersPeaks[indexPath.row])cell?.setHeight(height: eightThousandersPeaksHeight[indexPath.row])return cell!}} - Select
Main.storyboard
to edit the storyboard. - Find in the object library a Table View and drag it over to the View window.
- Add all necessary constraints to make sure that the table view is positioned and sized correctly.
- Now we have to link the table view to the outlet. Select the
Main.storyboard
file and in the Document Outline, Control-drag from the View Controller icon to the Table View icon. Release the mouse and selecttableView
in the pop-up.
- Set our controller class the data source for the table as we did it in Table views basics (Swift): Step 2: add Table view and set connections: substep 5
- Select the table view in the Document Inspector and bring up the Connections Inspector (use shortcut: Alt + Command + 6).
- Drag from the circle next to dataSource in Outlets section to the View Controller icon in the Document Outline or above the view controller in the storyboard editor. This makes our controller class the data source for this table.
- Single-click
- Step 4: design table view cell in Interface Builder
- Select
PeakInfoCell.xib
in the Project Navigator to open the file for editing. - Look in the library for a Table View Cell and drag it to the GUI layout area. In my case this cell was already created, so there was no need for manual addition.
- In the the Attributes Inspector set the Identifier value to
PeakInfoCellIdentifier
- Select the table cell in the editing area to edit our table cell’s content view. Go to the library, drag out two Label controls, and place them in the content view where you want. Next set some font attributes. In my case left label (name label) was set to System Bold 20 and right label (height) to System Italic 17. Remember also to set correct constraints. Doing that, have in mind that working with Auto Layout we have to set Top and Leading constraints as we do in most cases, but dynamic row height also requires bottom constraints (see Woodster's explanation in Detected a case where constraints ambiguously suggest a height of zero).
- Select the table view cell by clicking PeakInfoCellIdentifier in the Document Outline,
bring up the Identity Inspector, and choosePeakInfoCell
as the Class in Custom Class section.
- Switch to the Connections Inspector, where we will see the
nameLabel
andheightLabel
outlets. Drag from thelabelName
outlet to the name label (left in my case) and from thelabelHeight
outlet to the height label (right).
- Select
- Step 5: run the application
Customizing table view cells with storyboard
We can also design table cells directly in the storyboard, which means that we don’t need to create an extra
nib
file. This is fine as long as we don’t want to share cell designs between different tables.
In this part we will do the same thing as we did in previous Customizing Table View Cells with nib files part but without nib files.
- Step 1: create a new project
Create a new project- Select File | New | Project...
- Select Single View Application on the template selection sheet.
- As the product name enter
iOS Table View Custom Cell Storyboard
- Set the Language to Swift. Because we will not use tests in this tutorial, you can leave both test check boxes unchecked as well as make sure the check box labeled Use Core Data is also unchecked
- Step 2: create a new class
- In the Project Navigator, right-click the iOS Table View Custom Cell Storyboard group and select New File....
- Choose Cocoa Touch Class from the iOS Source section in the template dialog and then press Next
- Name the new class
PeakInfoCell
, make it a subclass ofUITableViewCell
. - Make sure that the Also create XIB file check box is NOT checked this time.
Press Next and then press Create to save the files.
- Step 3: add a new code and a table view
- Single-click
PeakInfoCell.swift
and add/modify the following code
12345678910111213141516171819202122232425262728293031323334import UIKitclass PeakInfoCell: UITableViewCell {var name = ""var height = ""@IBOutlet weak var labelName: UILabel!@IBOutlet weak var labelHeight: 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}func setName(name: String) {if !self.name.elementsEqual(name) {self.name = nameself.labelName.text = self.name}}func setHeight(height: String) {if !self.height.elementsEqual(height) {self.height = heightself.labelHeight.text = self.height}}} - Single-click
ViewController.swift
and add/modify the following code
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950import UIKit// Trick to get static variable in Swiftstruct staticVariable { static let PeakInfoCellIdentifier = "PeakInfoCellIdentifier" }class ViewController: UIViewController, UITableViewDataSource {var eightThousandersPeaks = [String]()var eightThousandersPeaksHeight = [String]()@IBOutlet weak var tableView: UITableView!override func viewDidLoad() {super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.eightThousandersPeaks += ["Mount Everest", "K2", "Kangchenjunga","Lhotse","Makalu", "Cho Oyu","Dhaulagiri","Manaslu", "Nanga Parbat","Annapurna I", "Gasherbrum I", "Broad Peak","Gasherbrum II", "Shishapangma"]eightThousandersPeaksHeight += ["8850", "8611", "8586","8516", "8463", "8201","8167", "8156", "8126","8091", "8068", "8047","8035", "8013"]}override func didReceiveMemoryWarning() {super.didReceiveMemoryWarning()// Dispose of any resources that can be recreated.}func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {return eightThousandersPeaks.count;}func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {var cell:PeakInfoCell? = (tableView.dequeueReusableCell(withIdentifier: staticVariable.PeakInfoCellIdentifier) as? PeakInfoCell)if cell == nil {cell = (UITableViewCell(style: .subtitle, reuseIdentifier: staticVariable.PeakInfoCellIdentifier) as? PeakInfoCell)}cell?.setName(name: eightThousandersPeaks[indexPath.row])cell?.setHeight(height: eightThousandersPeaksHeight[indexPath.row])return cell!}} - Select
Main.storyboard
to edit the storyboard. - Find in the object library a Table View and drag it over to the View window.
- Add all necessary constraints to make sure that the table view is positioned and sized correctly
- Single-click
- Step 4: design table view cell in the storyboard
- Find in the object library a Table View Cell and drag it over to the Table View window.
- In the Table View Cell section of Attributes inspector set
- Style as Custom,
- Identifier as
PeakInfoCellIdentifier
.
- Select the table cell in the editing area to edit our table cell’s content view. Go to the library, drag out two Label controls, and place them in the content view where you want. Next set some font attributes. In my case left label (name label) was set to System Bold 20 and right label (height) to System Italic 17. Remember also to set correct constraints.
- Select Main.storyboard, then the table view cell by clicking PeakInfoCellIdentifier in the Document Outline, bring up the Identity Inspector, and choose
PeakInfoCell
as the Class in Custom Class section.
- Switch to the Connections Inspector, where we will see the
nameLabel
andheightLabel
outlets. Drag from thenameLabel
outlet to the name label (left in my case) and from theheightLabel
outlet to the height label (right).
- Now we have to link the table view to the outlet. Select the
Main.storyboard
file and in the Document Outline, Control-drag from the View Controller icon to the Table View icon. Release the mouse and selecttableView
in the pop-up.
- Set our controller class the data source for the table
- Select the table view in the Document Inspector and bring up the Connections Inspector (use shortcut: Alt + Command + 6).
- Drag from the circle next to dataSource in Outlets section to the View Controller icon in the Document Outline or above the view controller in the storyboard editor. This makes our controller class the data source for this table.
- Find in the object library a Table View Cell and drag it over to the Table View window.
- Step 5: run the application
Customizing table view programmatically