Dealing with the triangles in a NSOutlineView
Monday, April 03, 2006
The first of which is a quick way to hide the little triangles in an outline view. I've searched many sites for an answer to this question and didn't really get an example of doing this. So here it is.
The first thing to make you aware of is that a NSOutlineView has a delegate method which allows you to override the display of the outline column's cell.
Here's the method...
- (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
Approach 1
Just replace the triangle images with other images. (This requires the image to be the same size as the triangle)
- (void)outlineView:(NSOutlineView *)theOutlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
if (item) {
[cell setImage:[NSImage imageNamed:@"down"]];
[cell setAlternateImage:[NSImage imageNamed:@"up"]];
}
}
Approach 2
First, hide the triangle completely.- (void)outlineView:(NSOutlineView *)theOutlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
if (item) {
[cell setTransparent:YES];
}
}
Now we use the non-outline delegate method to set up a button cell to do the expand and collapse for the row.
- (void)outlineView:(NSOutlineView *)theOutlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
if ([[tableColumn identifier] isEqualToString:@"outline"]) { //use the appropriate identifier for you column
if ([self childCountOfItem:item] > 0) {
if ([theOutlineView isItemExpanded:item]) {
[cell setImage:[NSImage imageNamed:@"up"]];
} else {
[cell setImage:[NSImage imageNamed:@"down"]];
}
//set up an action to emulate the clicking you would normally do on the triangle
[cell setAction:@selector(toggleItem:)];
[cell setTarget:self];
} else {
[cell setImage:[NSImage imageNamed:@"unexpandable"]];
}
}
}
- (void)toggleItem:(id)sender {
id item = [outlineView itemAtRow:[outlineView selectedRow]];
if ([outlineView isItemExpanded:item]) {
[outlineView collapseItem:item];
} else {
[outlineView expandItem:item];
}
}
As always feedback is encouraged...