I'm using a view based NSOutlineView that has it's selectionHighlightStyle set to NSTableViewSelectionHighlightStyleSourceList.
I want to overwrite the selection style (background) for certain rows and draw a different color/gradient.
What I tried so far is creating a custom NSTableRowView and returning it via outlineView:rowViewForItem:.
I verified that my custom row views are created and returned by the outline view delegate.
However, none of the methods I'm overwriting in the custom row view are being called.
I tried to overwrite drawBackgroundInRect:, drawSelectionInRect:, drawSeparatorInRect: and even drawRect:. None of those are called, ever.
I'm suspecting the outline view to be doing some custom "magic" when it's set to the source list style, but I've not found anything in the documentation that indicates that a custom NSTableRowView wouldn't be honored at all in this case.
AppKit adds separate NSVisualEffectView with custom material to row view for drawing background when using NSTableViewSelectionHighlightStyleSourceList. I've come up with the following workaround which uses zero private APIs, but can break later if Apple implements some other way of highlighting rows.
@class CustomHighlightRowSelectionView;
@interface CustomHighlightRowView : NSTableRowView
@property (nonatomic, strong) CustomHighlightRowSelectionView *selectionView;
@end
@interface CustomHighlightRowSelectionView : NSView
@property (nonatomic, getter=isEmphasized) BOOL emphasized;
@property (nonatomic, getter=isSelected) BOOL selected;
@end
@implementation CustomHighlightRowView
- (CustomHighlightRowSelectionView *)selectionView
{
if (!_selectionView)
{
_selectionView = [[CustomHighlightRowSelectionView alloc] initWithFrame:NSZeroRect];
}
return _selectionView;
}
- (void)setEmphasized:(BOOL)emphasized
{
[super setEmphasized:emphasized];
self.selectionView.emphasized = emphasized;
}
- (void)setSelected:(BOOL)selected
{
[super setSelected:selected];
self.selectionView.selected = selected;
}
- (void)addSubview:(NSView *)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView *)otherView
{
if (![aView isKindOfClass:[NSVisualEffectView class]])
{
[super addSubview:aView positioned:place relativeTo:otherView];
}
else
{
if (!self.selectionView.superview)
{
[super addSubview:self.selectionView positioned:place relativeTo:otherView];
self.selectionView.frame = self.bounds;
}
}
}
- (void)setFrame:(NSRect)frame
{
[super setFrame:frame];
self.selectionView.frame = self.bounds;
}
- (void)setBounds:(NSRect)bounds
{
[super setBounds:bounds];
self.selectionView.frame = self.bounds;
}
@end
@implementation CustomHighlightRowSelectionView
- (void)setEmphasized:(BOOL)emphasized
{
_emphasized = emphasized;
[self setNeedsDisplay:YES];
}
- (void)setSelected:(BOOL)selected
{
_selected = selected;
[self setNeedsDisplay:YES];
}
- (void)drawRect:(NSRect)dirtyRect
{
if (!self.selected)
{
return;
}
NSColor *fillColor = self.emphasized ? [NSColor alternateSelectedControlColor] : [NSColor secondarySelectedControlColor];
[fillColor setFill];
NSRectFill(dirtyRect);
}
@end
Are you using Yosemite? From Apple's document Adopting Advanced Features of the new UI in Yosemite
When selectionHighlightStyle == NSTableViewSelectionHighlightStyleSourceList • Selection is now a special blue material that does behind window blending - The material size and drawing can not be customized
If you set it to NSTableViewSelectionHighlightStyleRegular and override the drawRect, it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With