核心动画 - 使用`makeBackingLayer`不适用核心图像滤镜

问题描述:

我正在构建一个CALayer支持的NSView,它将遮罩过滤器应用到图层,然后绘制图层。当我建立一个新图层并在-(void)viewDidMoveToSuperview)中手动设置该视图时,该视图呈现正确,但是当我覆盖-(CALayer *)makeBackingLayer时,滤镜不会应用于图层。核心动画 - 使用`makeBackingLayer`不适用核心图像滤镜

下面是工作的代码(层主视图样式):

-(void)viewDidMoveToSuperview{ 
    [super viewDidMoveToSuperview]; 
    CIFilter *filter = [CIFilter filterWithName:@"CIBlendWithMask"]; 
    [filter setValue:[self transparentImage] forKey:@"inputBackgroundImage"]; 
    [filter setValue:[self maskImage] forKey:@"inputMaskImage"]; 

    self.layer = [TransparentLayer layer]; 
    self.layer.backgroundColor = CGColorCreateGenericRGB(0, 1, 1, 1); 

    [self.layer setPosition:CGPointMake(0 ,0)]; 
    [self.layer setAnchorPoint:CGPointMake(0 ,0)]; 
    [self.layer setBounds:CGRectMake(0 ,0 ,200, 200)]; 
    self.layer.filters = [NSArray arrayWithObject:filter]; 
    [self setWantsLayer:YES]; 
    [self.layer setNeedsDisplay]; 
    [self setNeedsDisplay:YES]; 
} 

这使得CALayer的和输出是这样的:

Layer Host

但是,当我做到这一点(层支持的视图样式):

-(CALayer *)makeBackingLayer{ 

    CIFilter *filter = [CIFilter filterWithName:@"CIBlendWithMask"]; 
    [filter setValue:[self transparentImage] forKey:@"inputBackgroundImage"]; 
    [filter setValue:[self maskImage] forKey:@"inputMaskImage"]; 

    TransparentLayer *backingLayer = [TransparentLayer layer]; 
    backingLayer.backgroundColor = CGColorCreateGenericRGB(0, 1, 1, 1); 

    [backingLayer setPosition:CGPointMake(0 ,0)]; 
    [backingLayer setAnchorPoint:CGPointMake(0 ,0)]; 
    [backingLayer setBounds:CGRectMake(0 ,0 ,200, 200)]; 
    backingLayer.filters = [NSArray arrayWithObject:filter]; 
    return backingLayer; 

} 

-(void)viewDidMoveToSuperview{ 
    [super viewDidMoveToSuperview]; 
    [self setWantsLayer:YES]; 
} 

视图结束这样看:

Layer Backed View (Broken)

两个问题:

1 - 使用makeBackingLayer时为什么没有应用层过滤器?

2 - 如何使用makeBackingLayer生成图层而不是调用setLayer

编辑:更改-(void)viewDidMoveToSuperView以下内容呈现层像我想它,但它仍然没有回答我的问题:既然你访问视图的层的属性,你必须做出

-(void)viewDidMoveToSuperview{ 
    [super viewDidMoveToSuperview]; 
    //manually set the layer 
    [self setLayer:[self makeBackingLayer]]; 
    [self setWantsLayer:YES]; 
} 

主机层而不是层支持的视图。

您不能使用-makeBackingLayer来自定义视图的图层。文档中提到只有一个应用这种方法:

在您的视图类,覆盖-makeBackingLayer来回报您NSOpenGLLayer子类的 自动释放实例。

  1. 因为你应该使用-setContentFilters:
  2. 你不能。您必须致电setLayer:

-makeBackingLayer是创建自定义图层的错误位置。您应该添加新的方法(例如-makeHostLayer)。

+0

答案#1(使用'-setContentFilters:')不适用于我。 (是旧的API还是iOS的具体?)但是,整体答案(使用图层托管视图而不是图层支持视图)是正确的。 谢谢Kentzo – jacobsimeon

+0

'-setContentFilters:'如果您的视图仅支持图层,则适用。 – Kentzo

+1

我认为这不是100%正确的,一般来说肯定你可以使用'makeBackingLayer'来创建你自己的支持层,这在[Core Animation Programming Guide]中有介绍(https://developer.apple.com/library/ mac/documentation/Cocoa/Conceptual/CoreAnimation_guide)[设置图层对象]部分(https://developer.apple。COM /库/ MAC /文档/可可/概念/ CoreAnimation_guide/SettingUpLayerObjects/SettingUpLayerObjects.html#// apple_ref/DOC/UID/TP40004514-CH13-SW12)。你必须调用这个'setWantsLayer:'。其余的是正确的,支持层不是图层托管。 – Stephan