【问题标题】:Core Animation - Using `makeBackingLayer` does not apply Core Image Filter核心动画 - 使用 `makeBackingLayer` 不应用核心图像过滤器
【发布时间】:2011-11-19 22:55:58
【问题描述】:

我正在构建一个支持 CALayer 的 NSView,它将蒙版过滤器应用于图层,然后绘制图层。当我在-(void)viewDidMoveToSuperview) 中手动构建一个新层并在视图上设置它时,视图会正确呈现,但是当我覆盖-(CALayer *)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,输出如下所示:

但是当我这样做时(图层支持的视图样式):

-(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];
}

视图最终看起来像这样:

两个问题:

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

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

编辑:将-(void)viewDidMoveToSuperView 更改为以下内容会像我想要的那样呈现图层,但它仍然没有回答我的问题:

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

【问题讨论】:

    标签: objective-c macos cocoa core-animation ios5


    【解决方案1】:

    由于您正在访问视图层的属性,因此您必须将视图设置为宿主层而不是支持层。

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

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

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

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

    【讨论】:

    • 答案#1(使用-setContentFilters:)对我不起作用。 (这是较旧的 API 还是特定于 iOS 的?)但是,总体答案(使用图层托管视图而不是图层支持视图)是正确的。谢谢肯佐
    • -setContentFilters: 在您的视图仅支持层的情况下有效。
    • 我认为这不是 100% 正确的,通常可以确保您可以使用 makeBackingLayer 创建自己的支持层,这在 Core Animation Programming Guide 部分的 Setting Up Layer Object 中有记录。你必须打电话给这个setWantsLayer:。其余的都是正确的,支持层不是层托管。
    • 在重新访问我编写的一些非常古老的代码时遇到了我自己的答案。尽管如此,从 10.15 开始,覆盖 -makeBackingLayer: 以返回 custom 层对 AppKit 不干涉它的视图做了一些事情。
    猜你喜欢
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    相关资源
    最近更新 更多