CALayer 过滤器覆盖其他子层
我正在开发一个信息亭类型的应用程序。我想在中间有一个徽标(可行)。现在我尝试在徽标周围添加一些浮动层。我可以绘制图层(在 drawDots 中),但是当我向其添加过滤器时 - 它会覆盖我绘制的徽标图层。我已经在这里复制了所有重要的代码。同样,如果我注释掉在 dotLayer 上设置过滤器数组的行,机器人点层的紫色方块和徽标是可见的,但是当我应用过滤器时 - 徽标不可见。我不太明白,因为我正在为这些设置正确的框架。我还尝试在 dotLayer 上使用子层做一些事情,看看是否有帮助。
- (void)awakeFromNib
{
// Initialization code here.
// The cursor isn't used for selection, so we hide it
[NSCursor hide];
// go full screen, as a kiosk application
[self enterFullScreenMode:[self.window screen] withOptions:NULL];
[self setupLayers];
[self drawDots];
// Make the window the first responder to get keystrokes
[self.window makeFirstResponder:self];
// bring the window to the front
[self.window makeKeyAndOrderFront:self];
}
- (void)drawDots
{
CGColorRef purpleColor = CGColorCreateGenericRGB(0.604, 0.247, 0.463, 1.0);
CGColorRef transparentColor = CGColorCreateGenericRGB(0, 0, 0, 1.0);
// CALayer *something = [CALayer layer];
// something.frame = NSMakeRect(15, 15, 60, 60);
CALayer *dotLayer = [CALayer layer];
dotLayer.frame = NSMakeRect(15, 15, 30, 30);
dotLayer.backgroundColor = purpleColor;
CIFilter *gradientFilter = [CIFilter filterWithName:@"CIGaussianGradient"];
[gradientFilter setDefaults];
[gradientFilter setValue:(id)[CIColor colorWithCGColor:purpleColor] forKey:@"inputColor0"];
[gradientFilter setValue:(id)[CIColor colorWithCGColor:transparentColor] forKey:@"inputColor1"];
[gradientFilter setValue:(id)[NSNumber numberWithFloat:20.0] forKey:@"inputRadius"];
// dotLayer.compositingFilter = gradientFilter;
dotLayer.filters = [NSArray arrayWithObject:(id)gradientFilter];
[rootLayer addSublayer:dotLayer];
// [dotLayer addSublayer:something];
//
// [rootLayer addSublayer:dotLayer];
}
- (void)setupLayers
{
// Setup vars
CGFloat mirroredOffset = 10.0f;
CGColorRef blackColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0);
CGColorRef transparentColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 0.0);
// Get the image
logo = [NSImage imageNamed:@"logo_300.png"];
// Get the positioning of the logo - middle of the screen
CGFloat logoWidth = [logo size].width;
CGFloat logoHeight = [logo size].height;
CGFloat imageX = [self frame].size.width / 2 - logoWidth / 2;
CGFloat imageY = [self frame].size.height / 2 - logoHeight / 2;
// Create the layer for the all content to be drawn on
rootLayer = [CALayer layer];
rootLayer.geometryFlipped = YES;
rootLayer.opaque = YES;
rootLayer.frame = [self frame];
rootLayer.backgroundColor = blackColor;
[self setLayer:rootLayer];
NSRect imageRect = NSMakeRect(imageX, imageY, logoWidth, logoHeight * 2 + mirroredOffset);
// Create the layer that holds the logo
CALayer *logoLayer = [CALayer layer];
logoLayer.frame = NSMakeRect(imageX, imageY, logoWidth, logoHeight);
[rootLayer addSublayer:logoLayer];
// Create the layer for the main logo
CALayer *mainLogo = [CALayer layer];
mainLogo.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
mainLogo.contents = logo;
[logoLayer addSublayer:mainLogo];
// Create the mirrored layer
CALayer *logoMirroredLayer = [CALayer layer];
logoMirroredLayer.frame = NSMakeRect(0, logoHeight + mirroredOffset, logoWidth, logoHeight);
[logoLayer addSublayer:logoMirroredLayer];
// Create the layer for the logo
CALayer *logoBase = [CALayer layer];
logoBase.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
logoBase.contents = logo;
[logoMirroredLayer addSublayer:logoBase];
// Create the gradient to make the mirrored effect
CAGradientLayer *gradientCover = [CAGradientLayer layer];
gradientCover.frame = NSMakeRect(0, 0, imageRect.size.width, imageRect.size.height);
gradientCover.colors = [NSArray arrayWithObjects:(id)blackColor, (id)transparentColor, nil];
gradientCover.locations = [NSArray arrayWithObjects:(id)[NSNumber numberWithFloat:0.0f], (id)[NSNumber numberWithFloat:1.0f], nil];
[logoMirroredLayer addSublayer:gradientCover];
// Flip the mirrored layer
CGAffineTransform rotateTransform = CGAffineTransformRotate(CGAffineTransformIdentity, 180.0f * M_PI / 180 );
[logoMirroredLayer setAffineTransform:rotateTransform];
// Make the mirrored layer see through
logoMirroredLayer.opacity = 0.3f;
[self setWantsLayer:YES];
}
@end
我不明白的是,其他子层是在此层之前添加的,并且该层的框架不覆盖显示徽标的位置。
I am working on a kiosk type application. I want to have a logo in the middle ( which works ). Now I'm trying to add some floating layers around the logo. I can draw the layer ( in drawDots ), but when I add a filter to it - it covers up the logo layers that I drew. I've copied all the important code here. Again, if I comment out the line that sets the filters array on the dotLayer, bot the purple square for the dot layer and the logo are visible, but when I apply the filter - the logo is not visible. I don't really understand since I am setting what should be the proper frames on these. I also tried to do something with a sublayer on the dotLayer to see if that would help.
- (void)awakeFromNib
{
// Initialization code here.
// The cursor isn't used for selection, so we hide it
[NSCursor hide];
// go full screen, as a kiosk application
[self enterFullScreenMode:[self.window screen] withOptions:NULL];
[self setupLayers];
[self drawDots];
// Make the window the first responder to get keystrokes
[self.window makeFirstResponder:self];
// bring the window to the front
[self.window makeKeyAndOrderFront:self];
}
- (void)drawDots
{
CGColorRef purpleColor = CGColorCreateGenericRGB(0.604, 0.247, 0.463, 1.0);
CGColorRef transparentColor = CGColorCreateGenericRGB(0, 0, 0, 1.0);
// CALayer *something = [CALayer layer];
// something.frame = NSMakeRect(15, 15, 60, 60);
CALayer *dotLayer = [CALayer layer];
dotLayer.frame = NSMakeRect(15, 15, 30, 30);
dotLayer.backgroundColor = purpleColor;
CIFilter *gradientFilter = [CIFilter filterWithName:@"CIGaussianGradient"];
[gradientFilter setDefaults];
[gradientFilter setValue:(id)[CIColor colorWithCGColor:purpleColor] forKey:@"inputColor0"];
[gradientFilter setValue:(id)[CIColor colorWithCGColor:transparentColor] forKey:@"inputColor1"];
[gradientFilter setValue:(id)[NSNumber numberWithFloat:20.0] forKey:@"inputRadius"];
// dotLayer.compositingFilter = gradientFilter;
dotLayer.filters = [NSArray arrayWithObject:(id)gradientFilter];
[rootLayer addSublayer:dotLayer];
// [dotLayer addSublayer:something];
//
// [rootLayer addSublayer:dotLayer];
}
- (void)setupLayers
{
// Setup vars
CGFloat mirroredOffset = 10.0f;
CGColorRef blackColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1.0);
CGColorRef transparentColor = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 0.0);
// Get the image
logo = [NSImage imageNamed:@"logo_300.png"];
// Get the positioning of the logo - middle of the screen
CGFloat logoWidth = [logo size].width;
CGFloat logoHeight = [logo size].height;
CGFloat imageX = [self frame].size.width / 2 - logoWidth / 2;
CGFloat imageY = [self frame].size.height / 2 - logoHeight / 2;
// Create the layer for the all content to be drawn on
rootLayer = [CALayer layer];
rootLayer.geometryFlipped = YES;
rootLayer.opaque = YES;
rootLayer.frame = [self frame];
rootLayer.backgroundColor = blackColor;
[self setLayer:rootLayer];
NSRect imageRect = NSMakeRect(imageX, imageY, logoWidth, logoHeight * 2 + mirroredOffset);
// Create the layer that holds the logo
CALayer *logoLayer = [CALayer layer];
logoLayer.frame = NSMakeRect(imageX, imageY, logoWidth, logoHeight);
[rootLayer addSublayer:logoLayer];
// Create the layer for the main logo
CALayer *mainLogo = [CALayer layer];
mainLogo.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
mainLogo.contents = logo;
[logoLayer addSublayer:mainLogo];
// Create the mirrored layer
CALayer *logoMirroredLayer = [CALayer layer];
logoMirroredLayer.frame = NSMakeRect(0, logoHeight + mirroredOffset, logoWidth, logoHeight);
[logoLayer addSublayer:logoMirroredLayer];
// Create the layer for the logo
CALayer *logoBase = [CALayer layer];
logoBase.frame = NSMakeRect(0, 0, logoWidth, logoHeight);
logoBase.contents = logo;
[logoMirroredLayer addSublayer:logoBase];
// Create the gradient to make the mirrored effect
CAGradientLayer *gradientCover = [CAGradientLayer layer];
gradientCover.frame = NSMakeRect(0, 0, imageRect.size.width, imageRect.size.height);
gradientCover.colors = [NSArray arrayWithObjects:(id)blackColor, (id)transparentColor, nil];
gradientCover.locations = [NSArray arrayWithObjects:(id)[NSNumber numberWithFloat:0.0f], (id)[NSNumber numberWithFloat:1.0f], nil];
[logoMirroredLayer addSublayer:gradientCover];
// Flip the mirrored layer
CGAffineTransform rotateTransform = CGAffineTransformRotate(CGAffineTransformIdentity, 180.0f * M_PI / 180 );
[logoMirroredLayer setAffineTransform:rotateTransform];
// Make the mirrored layer see through
logoMirroredLayer.opacity = 0.3f;
[self setWantsLayer:YES];
}
@end
What I don't understand is that the other sub-layers are added before this one and the frame for this layer doesn't cover where the logo is displayed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的 CALayer 的 mask 是什么样的? CIFilter 可能会将您的 Alpha 通道设置为非零,从而遮挡其后面的图层。
What does your CALayer's mask look like? The CIFilter could be setting your alpha channel to non-zero thus occluding the layers behind it.