I’m over using UITableViewControllers

Background

Table views are scrollable vertical lists and are among the most popular iOS UI elements. The UITableView class doesn’t determine the data to be shown or what happens when a row in the table is selected. For that, it depends on protocols. Protocols are kinda like a job description, in that they are a set of minimum requirements. An object (or value type) that “conforms” to a protocol agrees to implement that protocol’s requirements, much like a contractor might agree to perform the functions listed in a statement of work. UITableViews have a required datasource property and an optional delegate property. These properties must be objects that conform to UITableViewDataSource and UITableViewDelegate, respectively.

The job of a ViewController in iOS is basically to present a screenful of views and lay them out properly. When View Controllers are subclassed, sometimes developers will add code to them that doesn’t relate to laying out views. This is done mostly because it’s easier in some ways to write methods in the class you’re already working on than to make a new class. However, when ViewControllers start doing work that isn’t related to controlling views, they become bloated and hard to maintain. They are sometimes jokingly referred to as ‘Massive View Controllers’ as a pun based on the Model-View-Controller architecture that iOS apps are supposed to be based on. Model-View-Controller is an architecture paradigm that says the details of the data model and the detail of the data presentation (views) are to be separated from each other.

Enter the UITableViewController.

Because UITableViews are such a popular UI element, often one of the first things an iOS developer learns is how to create and display a table. Very often, they are taught to do so using a UITableViewController, which is a view controller that displays a full-screen UITableView… and sets itself as the UITableView’s data source… and as the delegate. This is like being a manager, posting two job descriptions, and then hiring yourself for both of them.

As a new developer, I was really happy to see that all of these responsibilities were being handled in one place. Later when I made my own custom view controllers, I mimicked this process of handling everything for a scene in the ViewController that presented it. I did this for years until I realized that I was littering my projects with Massive View Controllers.

Every view controller I used was doing way more work than it should. I started breaking things apart and realized that this behavior started with me mimicking the UITableViewController. In recent years, I don’t use the UITableViewController at all. If I need a table, I’ll add it to a UIViewController and create a separate datasource class that conforms to the UITableViewDataSource protocol in a different file. This keeps things tidy and prevents my temptation to fall back into the Massive View Controller trap.

As a boilerplate project for a monthly Meetup I host at the Victoria Garden’s Apple Store, I made this sample project that demonstrates building a simple to-do list using a UIViewContoller with a table instead of a UITableViewController and a data source in a separate file.

Check it out if you’re interested: Simple To Do