Don’t use UITableViewController. Really.
I was hesitant to even begin writing this blogpost for two reasons. First of all, I knew it would be short. More importantly, though, it’s because I know some people swear by the opposite. However, I must insist that you should never use a UITableViewController in your iPhone applications.
Let’s go over the reasons to use a UITableViewController.
- It’s a subclass of UIViewController, so it’s simple to use.
- UITableViews must have a delegate and a datasource. UITableViewControllers automatically conform to the requisite protocols. The file template even comes with the necessary methods included.
Really, when you think about them, both of those two points are non issues. If UITableViewController is a subclass of UIViewController, why not just use a UIViewController with a UITableView on top of it? Also, conforming to to the delegate and datasource protocols is as simple as adding
Let’s now cover a few reasons why you won’t want to use a UITableViewController.
- You can not set the background to a custom image. You can only set the UITableView’s background color property. This stifles the UI possibilities within your application. While using the UIViewController, you get full access to its view property; meaning, you get full access to make the background whatever you want the background to be. If you feel so inclined, go ahead and stick a UIImageView in between your view controller’s view and the UITableView. If you set the UITableView’s background color to clearColor, you’ll see the image shining through!
- You must have the table sized to be full screen (minus status bar height, navbar height, and tab bar height, if applicable). Why would you want to resize a table? Consider UITableView’s header view. Table headers are nice, really; the problem is that they scroll with your UITableView. Using a UIViewController allows you to use a smaller table and your own non scrolling header above it. It really does make your application look better.
- Have you ever needed to attach a subview in a UITableViewController? It’s not very pretty. Mostly because a UITableView is a subclass of a UIScrollView. I’m sure you can think of a few reasons not to add subviews to a scrollview. However, adding a subview onto your UIViewController is super easy and recommended. It will not only make the new view a subview of your view controller’s main view, but it ensures that the subview does not scroll along with the table. This is ideal when you want to display a pop up message to your user, briefly display a view over your table that dims the table and makes it inaccessible to touches, or if you simply want to present some options. Take a look at this screenshot from FlowChat, the iPhone irc client by my friends over at brancipater. [/commercial]
Here are a couple of examples of some things that would be impossible to make using a UITableViewController.
Shrinking Table (think Spotlight/Weather): Click to watch video.
Backgrounds: 
Elaborate headers:
Really, the above image can be achieved with the UITableView’s headerView property, but then it would scroll along with the table, and that is undesired.
Comments
17 Comments on Don’t use UITableViewController. Really.
-
James on
Thu, 29th Oct 2009 8:09 am
-
Paul on
Mon, 18th Jan 2010 6:40 pm
-
Craig on
Wed, 20th Jan 2010 12:20 pm
-
Pierre on
Wed, 27th Jan 2010 6:31 pm
-
Skylar on
Wed, 27th Jan 2010 10:21 pm
-
Skylar on
Fri, 29th Jan 2010 9:36 pm
-
Will Homer on
Tue, 2nd Feb 2010 7:35 pm
-
Andrea on
Thu, 13th May 2010 1:48 am
-
Rafael on
Wed, 21st Jul 2010 3:27 pm
-
Andy on
Tue, 12th Apr 2011 8:59 am
-
James on
Tue, 3rd May 2011 5:31 pm
-
Paul on
Wed, 22nd Jun 2011 1:25 am
-
Merlin on
Wed, 6th Jul 2011 11:15 pm
-
Raci on
Thu, 11th Aug 2011 6:55 pm
-
Genmenor on
Wed, 31st Aug 2011 3:51 pm
-
C.j.d on
Mon, 26th Sep 2011 10:02 pm
-
Marcel Bradea on
Thu, 10th Nov 2011 8:40 pm
Thanks for this post. very insightful and ive often wondered the same reason for using a tableviewcontroller, when a viewcontroller is much easier to customize
This is working for for everything but the keyboard. I have a UITextView in one or two of the cells and when the keyboard appears and disappears, I can’t get the animation to come out perfect. I spent a day or two over the holidays trying to figure it out and ended up going back to the UITableViewController.
Good points, except, the only reason people use a UITableViewController is because it gives automatic scrolling of the table when using UITextFields within the table…a very common scenario in iPhone development…
Try it without and the keyboard will obscure the lower fields… and so the decision is made for you.. if you have a form page with more than say 5 elements, you’ll need UITableViewController… period.
Great article!
I tend to agree with you, your approach allows much more options.It’s worth mentioning though tha there actually is a way to have a background image with a UITable ViewController:
self.tableView.backgroundColor =[UIColor clearColor];
self.tableView.separatorColor = [UIColor clearColor];
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"default.png"]];
Pierre
Pierre, there are two issues with your work around. First of all, you are setting the background of the parent view controller. Often times, this is a navigation or tab bar controller. While this certainly is acceptable for this table, it may cause ill suited backgrounds for any other tables presented.
The second, and arguably more important, reason has to do with the drawing. What you are essentially doing is telling the device to draw two controllers: the one with the image, and the one that’s transparent. If you use a view controller with a background image, which is by default opaque, then the device won’t (or shouldn’t, I haven’t experimented) draw what’s hidden by the colored background image. Effectively reducing draw time and increasing performance.
Of course, this talk about table backgrounds is almost moot, what with 3.2’s newly added UITableView API. Regardless, you’ll want to keep this in mind if you want to back apps that are compatible with older versions of the OS.
While i agree with not liking UITableViewControllers I recently was doing a project where it was much easier to use one. During this project though that some of the things you suggested are possible. For example if you want a view that does not scroll with the table you can simply add it to the superview, for example:
[self.view addSubview:datePickerView];
Will scroll with the table but,
[self.view.superview addSubview:datePickerView];
Won’t scroll with the and then you just resize the table frame so it does not hide any cells.
[[self tableView] setFrame:CGRectMake(0,0,320,200)];
The same may also apply to things like background colour also although I have not tested it. I’m not sure if this would work in Interface Builder though as I do not own a Mac so all my UI’s are written programmatically using Linux.
Hi Will Homer,
I’ve tried as you said but it doesn’t work in my case.
I’ve initialized the tableViewController in my AppDelegate and passed it to the TabController with the method -initWithRootController.
I’ve tried to add the NavBar both in -viewWillAppear and -viewDidLoad. In the first case I obtain a full screen navbar, in the second just the tableView.
Tried also with the system here but the navbar scroll within the tableView :http://dlinsin.blogspot.com/2010/01/adding-uinavigationbar-to-uitableview.html
Hi I have find one case where we just can use the UITableViewController, when we have a UIViewController and inside a UIScrollViewController and try to add a UIViewController with UITableView inside the UIScrollView we hack a crash, in this case we have just one option: use UITableViewController
If you have any other option to this case, i will be very glad.
Best.
PS: I comment two because the first my email is wrong, if you answer please use this email
Thanks for your tutorial. I was so hung-up on the background image trick not working out so well with a UITableViewController and your solution helped me get it to work.
Skylar,
Seeing that this blog is a little older, I am hoping you might still be able to help me out. I have an app that is already working, but in the always striving for a better one, I am wanting to add this UIAlertView with and embedded TableView to one of my UIViews, which presently already uses UIAlertViews to allert the user to an error if one occurs. that being said, I am feeling a bit slow, as I can’t for the life of me figure out how to integrate your example into my app.
the details…
What I want to do, is to retrieve MetaData from dropBox Cloud Server, and post to an Array (TableView) the available files for backup, depending on how often someone backs up, there could be many or just a few depending on the preferences of the user. when they select the appropriate file, I want them to be able to just select the file and have the alert view pass the notification to the download method.
you mentioned that this code is easily reusable, but I don’t see it, am I missing something? I have followed your example app, and see that you have created an app to supply data to the TableView, but I am still a bit lost. can you dumb it down for me, or explain in better detail where to put the code when integrating to an existing app..
Hi James – There is example code for exactly what you described – an embedded UITableView inside a UIAlertView – in the book iPhone SDK 3 Programming by Maher Ali. I just happened to check it out today and found that.
*Thank you* for this post. I was wondering if I’m stupid, or there is really very little benefit to using UITableVIewController.
Definitely I agree, but UITableViewController has some benefits. Thus I would say UITableView gives you more control.
Merlin,
UITableViewController is just not so much generic. But if serves you, why cant use it?
Hello,Skylar
Thank you for your post,it very helpful.
But I had problem when I change to use UITableView included UIViewController from using UITableViewController.
When I init a NavigationController with a UITableViewController,if NavigationController.view.frame’s size was changed,UITableViewContoller’s tableView also changed itself automaticlly,but UIViewController.tableView’s size do not change.
For example,I create a view like this:
rootViewController(adBannerView,navigationController)
navigationController(viewController)
viewController(datePicker,tableView)
ps:a(b) means a include b
so when I change adBannerView’s position,I need resize navigationController.view.size to let adBannerView do not cover the tableView.
Anyone can help me?This problem really confused me very much…
Great post. Exactly the advice I was bouncing around in my head looking at UITableViewController. Comes way too prepackaged and rigid.
Cheers!
Tell me what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!
