15

I've made a view in my storyboard which I've now decided I'd rather display its data via static table cells.

I can't use static table views in a UIViewController (Static table views are only valid when embedded in UITableViewController instances). So, I need to convert my existing UIViewController to a UITableViewController somehow. I've changed the .h file's parent, but that hasn't done it.

Is there another way to get this going? I'd really rather not have to make a new VC in the storyboard and move everything over, it's a big hassle.

Luke
  • 9,512
  • 15
  • 82
  • 146
  • 2
    You have to physically replace the view controller object in interface builder with a table view controller. – Mick MacCallum Dec 19 '12 at 17:01
  • That's what I'm asking if there's an alternative to. – Luke Dec 19 '12 at 17:02
  • If I use a `UITableViewController`, can I have the table view itself not take up the entire screen on an iPhone? I'd like some other UI elements to be there, too (labels, buttons), and I don't want to put them inside cells. – Luke Dec 19 '12 at 17:05
  • You can't do that unless you embed the tableViewController in a container view. – rdelmar Dec 19 '12 at 18:05

3 Answers3

18

I'll add to this, since the question is about how to change a UIViewController into a UITableViewController, and given that this question is over a year old and the original answer, while valid and may or may not have been the only solution at the time, doesn't actually answer the question and is not the only solution.

It IS possible to do this, you just have to set up the table view delegate and datasource outlets in IB, and manually edit the storyboard XML, which sounds scary but is actually very easy.

First, change your class's parent to be a UITableViewController. UITableViewController already adopts the UITableViewDatasource and UITableViewDelegate protocols, so if your class does too you can remove them:

@implementation MyTableViewController : UITableViewController
...
@end

Next, create new referencing outlets on your UITableView for its dataSource and delegate. The easiest way to do this is to control-drag from the UITableView to itself. The popup will give you the dataSource and delegate options.

Lastly, you need to change the storyboard XML. The storyboard file can get pretty big pretty fast. The easiest way to find the scene you are looking for is by setting Storyboard Identifier in the Identity Inspector. To view the XML directly, right click on the storyboard file in the project navigator and select "Open As -> Source Code". Now just search for whatever you set the reuse identifier to earlier. You'll see something similar to this:

<!-- My Table View Controller -->
<scene sceneID="EuE-XX-cCb">
  <objects>
    <viewController storyboardIdentifier="MY_TABLE_VIEW_IDENTIFIER" ... >
      // Lots of other stuff
    </viewController>
  </objects>
</scene>

All you need to do is change the opening and closing view controller tags

<viewController>
</viewController>

to be tableViewController instead

<tableViewController>
</tableViewController>

That's it! No need to create a new UITableViewController scene or embed a UITableViewController in a container view.

EDIT:

I should also add that the UITableView MUST be the root view. It cannot be embedded inside another UIView.

Jordan
  • 4,133
  • 1
  • 27
  • 43
  • I've tried this solution and I can't get it to work. Anything I do results either in all subviews being thrown out, Xcode happily saying "I've fixed 8 issues for ya" (if I remove tableViewController). Do you have some experience with this problem? – Dalibor Filus Oct 08 '14 at 12:11
  • I've only had to do this a couple of times and I haven't ever had it toss out the subviews or correct things for me, sorry. This was working with Xcode 5.1 storyboards last I checked. Haven't tried it for Xcode6 storyboards yet though. Which version are you using? – Jordan Oct 09 '14 at 16:28
  • Eventually got it working in Xcode 6, but had to remove as much as possible, taking it down to the bare view. Only then could I rename the element. – Daniel P Nov 15 '14 at 22:15
  • Yeah, it has to be the very first, and only, immediate child element of the objects element. It cannot have any sibling elements and it cannot be a child element of another view. – Jordan Nov 18 '14 at 03:37
  • This was super helpful and saved me some time. This works the same in Xcode 6.1.1. Definitely use the Document Outline and remove views first, then drag a UITableView into the Document Outline as the first view. When you remove the View object, Top Layout Guide and Bottom Layout Guide will go away too, which is what you want. Very good tip to give the view controller a storyboard identifier, so that it's easy to locate in the XML. – mbeaty Feb 26 '15 at 16:54
  • Thank you, very helpful. I used this to change the detail view of the master-detail template into a tableView. (Xcode 7) – matt_s Oct 07 '15 at 21:23
13

If you want your static cell table view not to take up the entire screen, then using a container view is the easiest way to go. Start with a regular UIViewController and drag a container view (next to normal UIView in the object list) into its view. Resize it however you want -- the storyboard will automatically provide a view controller connected to this container view with an embed segue. Delete that controller, drag out a table view controller and right-drag from the container view to this table view controller to make a new embed segue. This table view controller can be accessed from the UIViewController with its childViewControllers property (and conversely, you can access the UIViewController from the table view controller with parentViewController if you need to).

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • 1
    Awesome, thanks. One thing I didn't get immediately was you don't add the Table View Controller under the container, you add it to the storyboard itself (after zooming out) and THEN you drag the segue from the container. – pfrank Sep 29 '13 at 02:32
1

What I did, is creating a UITableViewController in IB, open the Storyboard with a text editor, and copy all the nodes inside from the UIViewController to the UITableViewController.

I think that with this way there's less risk of deleting something important.

Before copying the sections objects, make sure that both tableviews (UIViewController and UITableViewController) have the same properties set like: static or dynamic cells, style (plain or grouped), etc.

mxch
  • 835
  • 2
  • 10
  • 20