I got some feedback to my last blog post about The best table view controller. In this post I want to comment on the feedback because the comment sections is not really good for detailed discussion.
I couldn’t get Interface Builder in Xcode 7.3 to support typed view controllers. While you can type in the associated class, the field becomes blank when the storyboard is saved.
Interesting. I wasn’t aware of this. But this again tells me, that storyboards (and the Interface Builder in general) are not suited for my style of iOS development. As you may know, I don’t like the Interface Builder.
If you depend on storyboards for your User Interface, than this kind of table view controller isn’t for you (yet).
Tables with multiple cell types would be problematic.
That is correct. In my experience, kind of 90% of the table views I build (during work and in my spare time) only have one cell type. In a future post I might investigate how to do something similar with more than one cell type. If you have an idea, please let me know.
There’s no way to cache or paginate date. Fine if the data set is small. More of a problem if you’re building the next Youtube.
This is not quite true. You can cache and paginate the date in the subclass or even better in the network layer. The networking code I have written for this demo project is quite simple. After watching the excellent talk by Marcus Zarra I would rewrite the networking to use NSOperation and some kind of caching mechanism. I’ll leave that for another post.
Hey Dominik, a noob question over here: why do you want to subclass uitableviewcontroller the way you did in your article? What are the advantages?
This is a big question here. Table views are so common in iOS development that I didn’t think about that many beginners might have problems to see why this might be a good (or a bad) idea. Instead of convincing beginners, that my approach is better than another approach, I will compare it to the way I wrote my table view controller code for a very long time.
Here is the
UserSerachTableViewController as I would have implemented years ago:
Let’s go through this step-by-step.
viewDidLoad() looks similar to my currently favorite version. The only difference is that we
have to add these calls:
Ok, not that bad. Next are the required method in the protocol
We need to implement those because
TraditionalUserSerachTableViewController is a subclass
UITableViewController and that conforms to
They look like this:
Still, very easy. In my currently preferred way those methods are
implemented in the base class
and therefore they don’t need to be implemented in the subclasses
because they inherit the implementations. We will see later, why this
might be a good idea.
Next, when the user taps a table view cell, the view controller showing the repositories should be pushed onto the navigation stack. This is the same as in the way I showed in the last blog post:
Nothing to explain here, I think (if you have questions, feel free to write a comment and I’ll explain further).
Finally the method that reacts on search requests by the user:
In contrast to the version from the last blog post, the network request
is in the delegate method of the search bar rather than in
didSet of the
searchString property. The latter has the advantage that, when ever the
searchString changes, a network request is executed. Therefore we only
need the network code at one place. In this case it doesn’t matter
because there is only one location in the code that talks to the
So in a direct comparison, my currently favorite method to build table view controllers doesn’t look as an advantage over the method I used years ago. The interesting part appears, when you have more than one table view controller. Than the approach with the base class wins, in my opinion, because a lot of the boiler plate code is the same or similar for all the table view controllers. Let’s have a look what the repository table view controller in the ‘traditional’ way would look like:
Again, this is not complicated and to write the code like that is
totally fine. But if you have a closer look at
tableView( :cellForRowAtIndexPath:), they look quite similar to the
An important principle in software development is:
Don’t Repeat Yourself (DRY)
This means, when ever you see code in your project that looks similar to other code in the same project, try to find a way to put that similarity into another class or struct or function to reduce doubling.
And that’s why I think the approach I have shown in the previous blog post is a good approach. It reduces doubling of code. And at the same time is quite easy to read, understand and maintain. Don’t be clever with your code. Be as simple and boring as you can.
I have added the ‘traditional’ code to the repository on github.
If you have some feedback or questions, please write a comment or contact me on Twitter.