Reputation: 2070
I have two NSViews, a
and b
. To be specific, a
is a WebView
and b
is an NSVisualEffectView
, but I don't think it matters.
a
has content in a non-rectangular alpha channel, and I would like to mask b
using a
's alpha channel. However, I would still like to display a
on top of b
, with b
remaining visible through the semi-transparent portions of a
.
I have a
and b
set up in Interface Builder and wired to my AppDelegate
. They are siblings, the only children of an NSWindow
's default NSView
. They are both constrained to fill the NSWindow entirely.
If I run the application now, I get a
displayed on top of b
Then, in applicationDidFinishLaunching:
, I call
((NSView*) self.window.contentView).wantsLayer = YES;
self.b.layer.mask = self.a.layer;
This results in b
being properly masked according to a
's alpha channel. However, a
is no longer visible. At this point, I don't know if a
is not being shown at all, or if it is simply being shown behind b
. I want to still be able to see a
, and see b
through any semi-transparent portions of a
. Is this possible simply by modifying the layer manipulation in some way?
Thank you.
Upvotes: 3
Views: 1673
Reputation: 29
Considering common usage of alpha-channels like in Photoshop, this already is the proper behavior. The concept of a mask is to cut pieces out of some otherwise rectangular image, the mask itself staying invisible. This gives you all options at hand. To have the "Mask" seen as well, it has to be displayed a second time, on top or at the bottom of the other elements (without being transformed into a mask), probably with some alpha value to make it partly transparent. The question now arises, depending on the specific mask element, if it could be simplified to save some memory - which is of course project dependent. I need transparent masked text in my about box (having the text fade out while being animated) and your code works just fine for me, and i tried to create what you want and here is the easiest way: As (test)mask view i created a semi-transparent one-colored star-shape in phososhop, flowing from full white to almost fully transparent. In IB i put this into an image-view that i named maskView and duplicated this one and named it maskLayer. The maskLayer is to be seen, the maskView is used to cut the text into a starry fading shape. The text is a Textfield on a CustomView, also in IB. I connected all three and into the windowController in the windowDidLoad i put my variation of your code:
- (void)windowDidLoad
{
[super windowDidLoad];
((NSView*) self.window.contentView).wantsLayer = YES;
[((NSView*) self.window.contentView) addSubview:maskLayer];
[((NSView*) self.window.contentView) addSubview:TextView];
[TextView addSubview:maskView];
TextView.layer.mask = maskView.layer;
}
This creates a semitransparent white star with black fading Text IN it, text that would overlap is being cut off :-D (it is important to mention, that maskLayer and maskView must be two different instances in IB, but they can share the same .png)
Upvotes: 1