NSVisual provides support for the user interface effects introduced in OS X Yosemite related to translucency, including “vibrant” appearances. To make the contents of a view blend with whatever is behind the view’s window or blend with contents of a view deeper in the view hierarchy, you contain the view in a visual effect view.
- macOS 10.10+
A visual effect view provides two different styles of translucency, as illustrated in the screenshot:
Behind-window blending allows whatever is behind the window to show through. This style is automatically set in many places, including sheets, pop-overs (
NSPopover), and table views using the source list selection highlight style.
In-window blending allows the window content to show through, and is automatically set for toolbars.
Vibrancy is associated with translucency. It describes a compositing mode that does special blending such as Plus Lighter, Plus Darker, Color Dodge, or Color Burn. The system automatically uses vibrancy in many places, including popovers, sheets, and sidebar table views. Some UI elements dynamically use vibrancy based on their contents. For example, an
NSText object uses vibrancy when certain special colors are used, such as
secondary. You may, though, need to support vibrancy in a custom view, or conversely you may need to disable vibrancy in a view.
The first step in supporting vibrancy in a view is to contain the view in an instance of
NSVisual. It is typically best to add vibrancy only to leaf views, not container views, because it is difficult to turn vibrancy off once it is on. In addition:
The view must implement
In most cases you set the appearance on the window or on the visual effect view—subviews then inherit the appearance.
If the blending mode is
within, the view must use Core Animation layers.
In this case it is best to set
trueon the parent view that contains the visual effect view, because blurring will occur with visual effect view and its subviews.
By default, if a view is set to be drawn as vibrant, both it and all of its subviews will be vibrant—a subview can not turn off vibrancy simply by returning
allows. Whether or how you can turn off vibrancy depends on the blending mode—this is because
NSVisual’s implementation of blurring and vibrancy itself depends on the blending mode:
In behind-window blending, the system describes a rectangle that should be blurred to the window server. Areas that should be vibrant are also described in a similar way. In this situation, you can opt-out rectangular shapes by adding another visual effect view with its state set to
inactive; you then add subviews to that.
Note that adding another visual effect view will make the rectangle containing the view non-vibrant, including anything drawn in that rectangle by the parent view. This may have the effect of showing up as darker or lighter rectangles around some views. The only solution in this case is for the entire view either to be vibrant or non vibrant. You can’t mix the two.
With in-window blending, vibrancy is achieved by setting the layer’s compositing filter. The compositing filter applies to the layer and all its children, that means a child view will always be vibrant. However, you can add non-vibrant sibling views over the vibrant view; the overlapping sibling views will not be vibrant.
You can optionally set the appearance to
NSAppearance to get the desired light or dark appearance. You can combine this with an appropriate light or dark material to get the desired vibrant look. Do not combine
NSAppearance with a light material because the resulting effect looks bad.