How to customize disclosure cell in view-based NSOutlineView

cocoa, disclosure, macos, nsoutlineview, osx-lion

Solution

This answer is written with OS X 10.7 in mind, for newer versions of OS X/macOS, refer to WetFish's answer

That method does not get called because it is only relevant for cell based outline views.

In a view based outline view, the disclosure triangle is a regular button in the row view of expandable rows. I don't know where it gets added, but it does, and `NSView`'s `didAddSubview:` method handles exactly that situation of a view being added somewhere else.

Hence, subclass `NSTableRowView`, and override `didAddSubview:`, like this:

-(void)didAddSubview:(NSView *)subview
{
    // As noted in the comments, don't forget to call super:
    [super didAddSubview:subview];

    if ( [subview isKindOfClass:[NSButton class]] ) {
        // This is (presumably) the button holding the 
        // outline triangle button.
        // We set our own images here.
        [(NSButton *)subview setImage:[NSImage imageNamed:@"disclosure-closed"]];
        [(NSButton *)subview setAlternateImage:[NSImage imageNamed:@"disclosure-open"]];
    }
}

Of course, your outline view's delegate will have to implement `outlineView:rowViewForItem:` to return the new row view.

Despite the name, `frameOfOutlineCellAtRow:` of `NSOutlineView` still gets called for view based outline views, so for the positioning of your triangle, you might want to subclass the outline view and override that method, too.

Problem

I'm trying to customize the disclosure arrow appearance in my view-based NSOutlineView. I saw that it's recommended to use ``` - (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item ``` delegate method to achieve it. The problem is that this method is not called for some reason. I have 2 custom cell views - one for item and second for header item. May be this method is not called for view-based outline views? May be something became broken in Lion? Please shed some light.

Original source