In the past few months I’ve been teaching myself how to code in Swift, a derivative of C++ After comparing my app to many other examples I dived into learning about UITableView’s and UITableViewCells. I got a massive headache. Every website I went on gave me different ways of doing it, some more complex than the other but I’m here to help, here’s my guide to getting started with UITableViews in Swift 4.
First, add a ‘Table View Controller’ to your storyboard, if it is going to be your main view ensure you tick ‘Is Initial View Controller’. Next, there are two methods we can use but I’m going to show you the more complex one as it is the one your more likely to use. Next we need a new file, so File -> New -> Swift File and name it cells.
Delete the contents of the file and change it to
import UIKit class myFirstCell: UITableViewCell { }
This defines the class myFirstCell as a UITableViewCell – Pretty self explanatory. Next we need to return to the storyboard and set the class of the ‘UITableViewCell’ to ‘myFirstCell’ This lets the system know that we’ll be using a custom cell that has its properties defined in the class ‘myFirstCell’
Head to the attributes inspector and ensure the identifier is set to ‘cell’. Before we go any further, let’s add some content to our cell. We’re going to have a users image, name, email address and contact number so lets design it. Next we need to connect it to our myFirstCell class. Open the assistant editor with our cells file on one side and the storyboard on the other. Now hold control and drag a label to the cells file and give it a name. By the end we should have four @IBOutlet connections in our cells file.
If we compile the app now nothing will happen because we haven’t set the UITableView up. Head to your ViewController file and add a new class named myFirstTableView and set the Table View in the Storyboard’s class to myFirstTableView
class myFirstTableView: UITableViewController { override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }
Next, we’re going to set the loading of data up. There are two essential methods for a Table View to work. They are ‘numberOfRowsInSection’ and ‘cellForRowAt’ which we define as follows
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { }
Doing this will generate errors that we’re not returning anything. To being with lets add ‘return 1’ to our ‘numberOfRowsInSection’ method. In the ‘cellForRowAt’ method we’re going to add the following
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! myFirstCell cell.name.text = "My First Contact" return cell
What happens if we run this now?
We can see a tiny bit of data but where is the rest of it? This is a common issue with custom cells. Return to your Storyboard and set the constraints, this is a more complex way to do it but this ensures no issues when we run the app.
Success! But we wan’t more contacts… So let’s expand and add two arrays to just below our class declaration.
let names = ["Bob", "John", "Mick", "Steve"] let numbers = ["070000000", "+447043532423", "+11325432432", "012324213112"] let email = ["hello@alexlamond.co.uk", "john@alexlamond.co.uk", "mick@alexlamond.co.uk", "noreply@alexlamond.co.uk"]
Replace the ‘return 1’ in ‘numberOfRowsInSection’ to names.count and change the ‘cellForRowAt’ code to
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! myFirstCell cell.name.text = names[indexPath.row] cell.phone.text = numbers[indexPath.row] cell.email.text = email[indexPath.row] cell.userImage.image = #imageLiteral(resourceName: "icons8-user_male_circle_filled.png") return cell
Now run the app and see your results. You can expand on this so much, you can add functions that get data from the web and show it in the table or add styles to cells based on data. Let’s add an extra array named favourite
let favourite = [true, true, false, true]
Now in our ‘cellForRowAt’ method, we’ll add a check
if favourite[indexPath.row] == true { cell.backgroundColor = .orange } else { //Always provide a default value to the cell as not doing this could cause incorrect cells to display as favourites cell.backgroundColor = .white }
Voila.