31

I am making an NSTableView programmatically but for some reason no matter what I do, I cannot make the darn headerView show up. It is imperative that I do this programmatically and not use the IB because I am actually developing this widget in an IDE called clozure cl which is a lisp ide that includes a cocoa bridge. Originally I thought this problem might have been caused by my development environement but I just created an example in Xcode using only objective C and it seems that the problem persists. What I do is pretty straightforward:

I make a window in the IB and in its awkefromnib methods I create and setup a table-view here is the code:

- (void)awakeFromNib {
mydatasource *data = [[mydatasource alloc] init];
NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:@"id"];
NSTableView *table = [[NSTableView alloc] initWithFrame: [[self                      

   contentView]frame]];
[table setDataSource:data];
[table addTableColumn:column];
[table addTableColumn:column];
[[self contentView] addSubview:table];
}

Here is the code for my data source object:

- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
printf("NUM ROwS");
    return 4;
}
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn    *)aTableColumn row:(NSInteger)rowIndex
{
 printf("THE OTHER ONE"); 
 return @"OKAY";
}

With this code I get a window with two colums and four rows and each cell displaying the string "OKAY", this is all fine and good except the table has no header. This might make sense except when I look at the tables header method, it has an initialized header with a frame whose values make sense. I am just wondering why I do not see it. Is there some special kind of magic I need to do so the header will display? I cannot seem to find any clues in the documentation. Once again it is imperative for the lisp ide that this be done programmatically so it would not be helpful no suggest using the IB which I know will have a working headerView. Thanks a lot.

Leo Dabus
  • 198,248
  • 51
  • 423
  • 494
Mike2012
  • 7,159
  • 13
  • 76
  • 131

3 Answers3

66

Here is some code to programmatically create a table view with a scroll bar, and multiple columns.

// create a table view and a scroll view
NSScrollView * tableContainer = [[NSScrollView alloc] initWithFrame:NSMakeRect(10, 10, 380, 200)];
NSTableView * tableView = [[NSTableView alloc] initWithFrame:NSMakeRect(0, 0, 364, 200)];
// create columns for our table
NSTableColumn * column1 = [[NSTableColumn alloc] initWithIdentifier:@"Col1"];
NSTableColumn * column2 = [[NSTableColumn alloc] initWithIdentifier:@"Col2"];
[column1 setWidth:252];
[column2 setWidth:198];
// generally you want to add at least one column to the table view.
[tableView addTableColumn:column1];
[tableView addTableColumn:column2];
[tableView setDelegate:self];
[tableView setDataSource:self];
[tableView reloadData];
// embed the table view in the scroll view, and add the scroll view
// to our window.
[tableContainer setDocumentView:tableView];
[tableContainer setHasVerticalScroller:YES];
[[self contentView] addSubview:tableContainer];
[tableContainer release];
[tableView release];
[column1 release];
[column2 release];

Just thought I would post this for anyone still looking for a straight forward answer. :)

Alex Nichol
  • 7,382
  • 4
  • 29
  • 28
  • Thank you! I had a XIB table view that refused to fetch cells and was not looking forward to translating that into code by hand. <3 – Kalle May 24 '14 at 13:56
  • 2
    Just a note. Embedding table view into a scroll view is essential to display everything correctly including headers. – eonil May 25 '14 at 23:25
  • Added a swift conversion below – Bjorn Jan 02 '15 at 19:13
21

I wrote this Swift version of @Alex Nichol's answer:

    let tableContainer = NSScrollView(frame:NSMakeRect(10, 10, 380, 200))
    let tableView = NSTableView(frame:NSMakeRect(0, 0, 364, 200))
    let column1 = NSTableColumn(identifier: "Col1")
    let column2 = NSTableColumn(identifier: "Col2")
    column1.width = 252
    column2.width = 198
    tableView.addTableColumn(column1)
    tableView.addTableColumn(column2)
    tableView.setDelegate(self)
    tableView.setDataSource(self)
    tableView.reloadData()
    tableContainer.documentView = tableView
    tableContainer.hasVerticalScroller = true
    window.contentView.addSubview(tableContainer)

It worked.

Bjorn
  • 60,553
  • 37
  • 128
  • 161
  • requires minor changes for latest swift but it works! – Are Butuv Mar 04 '18 at 06:20
  • 1
    If you implement this and add to a view that has constraints, the NSMakeRect values are irrelevant, but since the only other init is with coder, you have to use it. – RobMac Jul 30 '19 at 01:27
11

Well I answered my own question and I thought this might be helpful to someone else, it seems that that the headerView will only show up if you add the tableview to a scrollview.

Mike2012
  • 7,159
  • 13
  • 76
  • 131
  • 1
    I think I can answer your question: `NSTableHeaderView` is an entirely different view (and class). It's just IB automatically throwing it at you if you drag out an NSTableView-set. I think IB should be more clear about what views come with such 'view sets'. – 11684 Mar 07 '13 at 17:06