NSVisualEffectView behind NSScrollView

2.1k Views Asked by At

I'm trying to get my NSScrollView (and thus a contained NSOutlineView) to use a blurred NSVisualEffectView with behind-window blending effect.

I've successfully made NSVisualEffectView the container view and placed my scroll view as a subview. This seems to work fine (as long as I make all my table cells, table, nsscrollview etc transparent).

However I've now turned 'Reduce transparency' ON under Accessibility options and all of a sudden I have a black background behind my NSScrollView. I tried subclassing the visual effect view in order to override the drawRect method so that I can draw my own background, but I've just learned this isn't possible or recommended.

How do I detect that Reduce Transparency is ON and how do I make my scrollview opaque dynamically?

3

There are 3 best solutions below

0
On BEST ANSWER

Took me a while to find it, but there are a couple of new methods on NSWorkspace that you can use to find out about the preferences for OS X Yosemite’s new accessibility features. -[NSWorkspace accessibilityDisplayShouldReduceTransparency] is the one you want.

By Listening for NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification you can find out when that preference changes. Note that you’ll have to register for that notification on the correct NSNotificationCenter, that is [[NSWorkspace sharedWorkspace] notificationCenter].

1
On

It seems as for now I've ended up overriding a parent NSView that contains everything and set a background color for that. This way, when Reduce Transparency is ON, the NSVisualEffectView becomes transparent and the color I end up getting is the one visible below it. This seems to work fine for now.

0
On

Despite we have SwiftUI nowadays, in classic Cocoa you can still subclass a custom NSScrollView and use ...

-(NSColor *)backgroundColor {
    return NSColor.clearColor; 
}
-(BOOL)drawsBackground {
    return NO;
}

or set properties of your NSScrollView accordingly if you don't want to subclass like...

yourscrollview.drawsBackground = NO;
yourscrollview.backgroundColor = NSColor.clearColor;

this forces your view to show what is below, and with it also the blurEffect or opaque color of your View or Window that is enclosing your NSScrollView.

This solution has the benefit that you do not have to observe the Workspace for some Notification or VibrancyEffect.