35

I have a NSTableView with the delegate and datasource pointing to my controller. I have tried implementing the

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex

Method, but no matter what I return, the table always shows "Table View Cell" in the data. Any ideas of what I could be doing wrong? Attached are two pics showing that I have the delegates set properly (it also shows the proper number of rows).

What the table shows enter image description here

Note that I have also just tried returning @"Hello World" for everything, but I get the same result.

albertamg
  • 28,492
  • 6
  • 64
  • 71
Kyle
  • 17,317
  • 32
  • 140
  • 246

6 Answers6

58

Just change the Content Mode to Cell Based for the table view in IB. IB will display Text Cell as the cell placeholders, which are populated at runtime by whatever you return from tableView:objectValueForTableColumn:row:

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
JAWZapps
  • 604
  • 6
  • 3
  • I had the same problem after working on an older project in Mavericks, and this solution worked for me. – Benjineer Dec 15 '13 at 05:27
11

Finally figured it out. My cells for some reason seem to contain both a TableCellView AND a text field cell. I removed the Table Cell View's and now everything is working. I have no idea how I got in that state.

enter image description here

Kyle
  • 17,317
  • 32
  • 140
  • 246
  • 2
    This is because you're using the new view mode that is found in Lion for the table in IB, but tableView:objectValueForTableColumn:row: is used for the old cell method. – iain Sep 24 '11 at 11:42
  • By default, XCode will put those Table Cell Views for you. But I also couldn't manage to put them to work. – gcstr Nov 15 '11 at 17:38
  • Thank you. This was exactly the problem I was having. everything was working, then suddenly it wasn't. I think a UI element was accidentally dragged into the tableViews areas and IB added the views for us. – Arr MiHardies Feb 11 '14 at 17:47
  • Good lord, took me forever to figure this out. Still a problem, even today. Dragged in the table view, table cell views came with it. – Steve Sep 16 '14 at 01:28
  • Worth to mention that selecting `Content Mode`: `Cell Based` as suggested by JAWZapps above deleted these extra entries for me without me having to do it manually. – RoyGal May 25 '15 at 06:41
10

Most of the responses involve converting the table view component to a cell-based table view. If that’s what you want then that’s fine, you’re good to go. At the time the question was asked, cell-based tables were the norm and when Apple changed the window component to a view-based one it obviously caused a lot of confusion. Today, Apple’s docs recommend that you should use view-based rather than cell-based tables.

The problem described in the question arises if you use - tableView:objectValueForTableColumn:row: in your datasource. You cannot use this method with view-based tables, it is only for cell-based tables. Instead you need to use the NSTableViewDelegate method - tableView:viewForTableColumn:row:. You don't need to make the object conform to the NSTableViewDelegate protocol to use this method but it must be set as the delegate of the table.

In response to Cœur, quoting from the Apple On-line docs.

NSCell-Based Tables Are Still Supported In OS X v10.6 and earlier, each table view cell was required to be a subclass of NSCell. This approach caused limitations when designing complex custom cells, often requiring you to write your own NSCell subclasses. Providing animation, such as progress views, was also extremely difficult. In this document these types of table views are referred to as NSCell-based table views. NSCell-based tables continue to be supported in OS X v10.7 and later, but they’re typically used only to support legacy code. In general, you should use NSView-based tables.

psmythirl
  • 309
  • 3
  • 11
9

Newer version of XCode:

  1. Select the table view (make sure the scroll view or any other view is not selected).
  2. On the right hand side, select the "Attribute Inspector"
  3. Change the Content Mode to "Cell Based" instead of "View Based"
  4. Save your changes and re-run the project.
Gaurav
  • 227
  • 3
  • 4
0

It looks like you might be missing the all-important -numberOfRowsInTableView: data source method. See Table View Programming Guide: (View-based table view) The Required Methods and Table View Programming Guide: (cell-based table view) Providing Data To a Table View Programmatically for details.

Basically, the very first NSTableViewDataSource method that's called is numberOfRowsInTableView:. Only after you return a non-zero quantity from within that method will the subsequent tableView:objectValueForTableColumn:row: or tableView:willDisplayCell:forTableColumn:row: methods be called.

NSGod
  • 22,699
  • 3
  • 58
  • 66
  • Sadly, I do have that method implemented and it seems to work properly. I get x number of 'Table View Cells' where x is the number returned from the numberOfRowsInTableView call :S – Kyle Sep 23 '11 at 21:16
-1

You're misunderstanding how the result of -tableView:objectValueForTableColumn:row: is used by the frameworks.

To do more-or-less what you're trying to accomplish above, override the delegate method -tableView:willDisplayCell:forTableColumn:row: instead. Here is an example cribbed from one of my own apps:

- (void)tableView:(NSTableView *)tableView
  willDisplayCell:(id)cell
   forTableColumn:(NSTableColumn *)tableColumn
              row:(NSInteger)row;
{
    NSString * displayName = [self.senders objectAtIndex:row];
    [cell setTitle:displayName];
    [cell setState:[self.selection containsObject:displayName]];
}

This is the "old school" way, using cell-based tables (which are still the default).

Kaelin Colclasure
  • 3,925
  • 1
  • 26
  • 36
  • Hm, I tried adding this as well and put in a NSLog message when it gets called, that I don't seem to be getting while its running :S – Kyle Sep 23 '11 at 21:20