问题
I'm still struggling with the view-based NSOutlineView in my little Cocoa application. I'm trying model my OutlineView after the finder one. When the Finder OutlineView loses focus (e.g. clicking any folder on the right side), the selected row (e.g. Desktop) stays selected with the bright blue gradient and does not change to the inactive blue-grey gradient.
I'd like to duplicate this behaviour in my application.
In a not view-based OutlineView I was able to subclass NSOutlineView and reimplement (void)highlightSelectionInClipRect:(NSRect)clipRect
, so that each highlighted row could be supplied with the bright blue background image.
However, now with my view-based OutlineView (set to SourceList style) this method apparently is not even called. I've even implemented (id)_highlightColorForCell:(NSCell *)cell
to return nil, as some sites suggest, but that doesn't help either.
Any hints on how I can set the highlight gradient in the view-based OutlineView?
回答1:
Are you doing any custom drawing that could be messing with things? As far as I can tell all the selection drawing is handled for you normally, check out the TableViewPlayground example (not Source-list style by default but that's an easy change to the XIB).
But failing that, according to the Mac OS X 10.7 doc entry on highlightSelectionInClipRect:
Note: This method should not be subclassed or overridden for a view-base table view. Instead, row drawing customization should be done by subclassing NSTableRowView.
So I think (I haven't tried any of this) like you'd want to subclass NSTableRowView, override drawSelectionInRect:
(there's an example in TableViewPlayground, and draw your selection. You could check for the app being active with [NSApp active]
or maybe use the self.emphasized
property like the example does.
You'd then return one of your custom NSTableRowViews in the NSOutlineViewDelegate protocol method (10.7 only!): (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item
Hope this works/helps!
I should note that TableViewPlayground example uses the outlineView:viewForTableColumn:item:
delegate method by default and does everything with NSTableViewCells, but if you add the rowViewForItem
method I mention above it is called. So I'm guessing you could use it to return a view for each row in it's entirety.
回答2:
Thanks, with your hint I was able to solve the problem quite easily. I subclassed NSTableRowView
and overwrote -(BOOL) isEmphasized
to always return true.
I then implemented -(NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item
in my OutlineViews delegate to return a item specific instance of my subclass by calling ClbTableRowView *result = [outlineView makeViewWithIdentifier:identifier owner:self];
Edit: Besides that, there also seems to be a pretty hidden way of using the custom NSTableRowView subclass by dropping a new NSView Object into the the OutlineView in Interface Builder. Then set the views class to your subclass and give it a userinterface item identifier of "NSTableViewRowViewKey", according to the Apple documentation.
来源:https://stackoverflow.com/questions/7214314/view-based-nsoutlineview-selection-gradient