UPDATE: Link to source complete source code (download)
I am trying to implement a view based NSOutlineView (Sourcelist), but I have run into problems. To illustrate, I have created a minimalistic example.
I have a simple class called Person. Each person has a name (NSString) and maybe also some children (NSArray). I have added an NSOutlineView, hooked it up to an IBOutlet, set myself as DataSource, and implemented the NSOutlineViewDataSource methods.
First consider the case of a CELL BASED NSOutlineView:
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
// We are at the root
if (!item)
{
return [self.persons count];
}
// We are at an internal node
Person *person = (Person *)item;
return [person.children count];
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
// We are at the root
if (!item)
{
return self.persons[index];
}
// We are at an internal node
Person *person = (Person *)item;
return person.children[index];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
Person *person = (Person *)item;
if ([person.children count] > 0)
{
return YES;
}
return NO;
}
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
Person *person = (Person *)item;
return person.name;
}
It works just as I expected:
However, if I go and change the NSOutlineView to VIEW BASED, things look very different. Now all the names are replaced by "Table View Cell". I have tried to fix the problem by returning an NSTableCellView instead:
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
Person *person = (Person *)item;
NSTableCellView *tableCellView = [outlineView makeViewWithIdentifier:@"PersonCell" owner:self];
tableCellView.textField.stringValue = person.name;
return tableCellView;
}
Without making further changes, this doesn't change anything. When I change the identifier of the TableCellView in my NSOutlineView to PersonCell,
all the cells end up empty. In fact, adding a simple NSLog statement in the outlineView:objectValueForTableColumn:byItem: function reveals that the function is never even called.
This approached has worked for me with standard NSTableViews, and since NSOutlineView is a subclass of NSTableView, I expected the same behavior here.
Any help is greatly appreciated.
Thanks!
/Michael Knudsen
I think the corresponding method to return the proper view objects for each row is
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
and not
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
You return a view, not an objectValue in view based table views.
So it should work using:
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item
Person *person = (Person *)item;
NSTableCellView *tableCellView = [outlineView makeViewWithIdentifier:@"PersonCell" owner:self];
tableCellView.textField.stringValue = person.name;
return tableCellView;
}