iOS Essentials: UITableView

Table views are everywhere in iOS. See a list in an app? It’s probably a table view. Social feeds. Recipe ingredients. Historical data. To-do lists. Settings screens. Shopping carts. Favorites and bookmarks. Navigation directions. Reading lists. Playlists. Schedules. Lists are everywhere in iOS, and table views are what they’re made of.

For specific examples, look no further than Apple’s own built-in apps. Settings. Mail. Notes. Calendar. Clock. App Store. Photos. Contacts. Phone. Health. Podcasts. Stocks. All of these apps use table views, and there are undoubtedly more. Plenty of third-party apps use them as well, and I’d bet that well over half of the apps on the App Store use at least one table view.

So table views are all over the place in iOS, and it should come as no surprise that if you’re planning to build iOS apps, you need to know all about table views. Let’s start with UITableView, the view you see when you look at a list in an iOS app. We’ll look at some of the properties and methods you’ll need as you create lists in your iOS apps.


Every table view needs a data source. Without one, your list is a list of nothing. A blank table – a bunch of empty rows.

The dataSource in your table view is an object that conforms to the UITableViewDataSource protocol. This object, the dataSource, tells your table view how many sections it should display and how many rows should be in each section. Additionally, it provides the view (or cell) for each row. You can learn more about the dataSource by reading Apple’s documentation, which summarizes its responsibility well:

The data source provides the table-view object with the information it needs to construct and modify a table view.

You might use your view controller as the dataSource like Apple does in much of their sample code, but I’d strongly urge you to reconsider that. If you want your view controllers to adhere to the single responsibility principle, you cannot make them the dataSource of your table view. It’s not always an easy thing to do, but it’s certainly a good thing to do and has the added benefit of reducing the size of your view controller.


The delegate deals with user interaction with your table view. When a user taps a cell or its accessory view, the delegate is notified so your code can take action. It also allows you to configure custom header and footer views for the sections in your table view and manage editing of your table view’s rows.

The delegate is an instance of an object that conforms to the UITableViewDelegate protocol. Since it deals with specific user interaction, you can get by without a delegate if your table view is just for display and navigation. You can transition to another view controller, and you can even pass data to that new view controller without a delegate. But you’ll need a delegate if you want to create custom section headers or footers, control row highlighting, allow editing, and more. Most of the time, I have a delegate connected to my table views, but it’s not exactly essential like the dataSource is.

You can learn more about the delegate in Apple’s documentation for UITableViewDelegate.


Almost always used in the UITableViewDataSource’s tableView:cellForRowAtIndexPath:, this is a quick & easy way to get a cell to configure and display. And it’s performant, too – when you get a cell this way, you’re getting a cell that’s already been loaded into memory. This results in vastly improved scrolling perfomance over the alternative – instantiating a new cell every time.

Most of the time, I use a generic identifier for my cells: “cell”, for example, and that works well enough. If your table view cells have different visual styles from each other, you might use different cell identifiers – such as one for the blue cells and one for the green cells in your table view.

Specifying in the indexPath parameter is trivial – you’ll just pass the indexPath you get in UITableViewDataSource’s tableView:cellForRowAtIndexPath: right in to this method.


Often you’ll be working with lists that can be updated, especially when your table view is backed by data from a network request. The table view will appear, you’ll make your JSON API request, and then you’ll need to show the data in your table view. And that’s when you call the table view’s reloadData() method. After the underlying data arrives or changes for any reason, you’ll call this, forcing the table view to display the new or updated data. Since this causes the UI to be updated, you need to make sure it’s called on the main thread – or you might not see the update.

Continue your journey to becoming an iOS developer

This is the second in the iOS Essentials series. If you missed the first, it’s here:

iOS Essentials: The UIViewController Lifecycle

And don’t stop here – continue learning iOS development with the free 5-Part Guide to Getting Started with Swift.