My steps using storyboard
Create a Mac Cocoa app using storyboard. Drag a Table View from the right sidebar onto the storyboard.
Let the pre-existing ViewController to follow NSTableViewDataSource protocol. Implement two methods in ViewController.m: numberOfRowsInTableView: returns 10 and tableView:objectValueForTableColumn:row: returns #"321".
In storyboard, connect the Table View's delegate and dataSource to (the only) View Controller.
The Problem
Every cell displays "Table View Cell" rather than the data I want to fill. In spite of that, tableView:objectValueForTableColumn:row: was indeed called 10 times.
The alternative using .xib
https://www.youtube.com/watch?v=p5U94-uRCOo
Use .xib rather than .storyboard. Drag a Table View from the right sidebar onto the storyboard.
Create a class MyTableViewController who follows NSTableViewDataSource protocol. Implement the same two methods.
In xib, drag a new object to the object. Change its class to MyTableViewController and connect the object to the table view's dataSource.
Your table view needs to be cell based not view based. Loot at the documentation.
tableView:objectValueForTableColumn:row: is for cell based tables and
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row is for view based table views.
Related
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.
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.
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).
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.
As we all know, table views in Cocoa Touch are one of the niftiest pieces of framework elements that's out there. As a convenience, Apple gave us a nice view controller class to encapsulate the functionality of a table view in a vc, the UITableViewController.
At the same time, there are times that we want to utilize the functionality of a table view without having it take up the whole screen. However, there seems to be no way to do this by subclassing UITableViewController. Instead, I had to hookup a table view and manually subscribe to the UITableViewDelegate and UITableViewDataSource. If I try to subclass UITableViewController, my app crashes before it can even put the view on-screen...
My question is, is there something I'm missing? When subclassing UITableViewController, I hook up my custom table view to the tableView property in UITableViewController. Is there something else I have to do?
UITableViewController only adds minor conveniences over UIViewController: it creates and positions the table view, hooks up the delegate & datasource (to itself, generally), passes the view controller editing property through to the table, and does a couple of useful UI bits when the view appears. (See [the docs][1] for details.)
Just about all of the above are either A) things that you're needing to change in order to have a non-fullscreen table, or B) things that you can do in a line or two each, and which UITableViewController only does for your convenience. For cases like this, you're better off using your own UIViewController subclass.
Step 1: Subclass UIViewController instead of UITableViewController
MyTableViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
Step 2: Use interface builder to drop a tableView and custom View
Step 3: Declare the tableView property as IBOutlet in your MyTableViewController header file and bind it to the tableView in the interface builder
IMHO, This process would give you more flexibility.
I have a UIViewController, with a UITableView which takes up half the screen.
I also have a subclassed UITableViewController, but I can't figure out how I would associate the subclassed UITableViewController with my table?
It is not clear from your question exactly why you are trying to create a UITableViewController and a UIViewController in this case. Do you have 2 different tables you are trying to control? Or are you trying to do something special to have 2 different controllers managing different parts of a view/subview hierarchy?
Typically, the table for a UITableViewController is created automatically or within a NIB file. From the UITableViewController documentation:
If a nib file is specified via the initWithNibName:bundle: method
(which is declared by the superclass UIViewController),
UITableViewController loads the table view archived in the nib file.
Otherwise, it creates an unconfigured UITableView object with the
correct dimensions and autoresize mask. You can access this view
through the tableView property.
So you would usually not need to associate your subclassed UITableViewController with its table because that is taken care of for you.
What is the difference between dragging a Table View Controller into the storyboard vs dragging a UI View Controller and dragging a Table View inside that in xCode?
I know how to populate a table view controller in code.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;
How do I populate a table view within a UI View Controller? What custom class do I delegate to the UI View? I cannot seem to put a tableViewController on it as it is only a ViewController with a table view...
I'd like to know this because I'd like to have objects other than the table in that view (i.e. a section of the view is for the table and the other section contains a label, an image, and a button.)
Populating a UITableView inside of a UIViewController is no different than populating a UITableView inside of a UITableViewController. You just have to make sure you implement the required datasource and delegate methods. You also need to be sure to assign the UIViewController as the delegate and the datasource for that UITableView.
If you want objects other than the table, then you should us a UIViewController. In fact, I rarely use the UITableViewController any more just in case I need to add other objects.
I found another difference too .
While using a UITableViewController , which has UIScrollView in it , the view scrolls up when keyboard moves up .
This doesn't happen with UIViewController as you need separate methods for View scrolling up and down .
You can also take a look at this
https://stackoverflow.com/a/14465669/5553647
Only UITableViewController can have static content. https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7-SW20
I currently have a UIViewController displaying a map view. I would like to display some custom table view cells when I tap on a button within the same UIViewController. Can I do that? Or do I need to set the table view cells within a UITableViewController?
Thanks for any advise here.
Zhen Hoe
You should use a UIViewController subclass rather than a subclass of UITableViewController to manage a table view if the view to be managed is composed of multiple subviews, one of which is a table view. The default behavior of the UITableViewController class is to make the table view fill the screen between the navigation bar and the tab bar (if either are present).
I would like to display some custom table view cells when I tap on a button within the same UIViewController.
If you want to show your table view along with other views, you can add a UITableView subview and make your controller implement UITableViewDelegateand UITableViewDataSource protocols.
You need to create a UITableViewController, and then set the contents of the UITableViewCells using the - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath delegate method.