将CALayer渲染到图像上下文会返回黑度

tob*_*jim 5 calayer ios

我的UIView子类广泛使用子层来构建复杂的图像.在屏幕和iPad 2上有多达30个这样的视图沿着perimeterPath(这是perimeterLayer的路径属性)的动画性能正在受到影响.

最初,我只是将构成图层添加为视图层的子图层.

[self.layer addSublayer:self.leftsideLayer];  // CAShapeLayer
[self.layer addSublayer:self.rightsideLayer]; // CAShapeLayer
[self.layer addSublayer:self.perimeterLayer]; // CAShapelayer
[self.layer addSublayer:self.valueLayer];     // CAShapeLayer
[self.layer insertSublayer:self.gradientLayer atIndex:0]; // CAGradientLayer + CAShapeLayer (as mask)
Run Code Online (Sandbox Code Playgroud)

屏幕渲染非常完美.但是由于动画开始滞后,我准备了这段代码,用于构建临时图层,目的是将临时图层渲染为位图.第一步是为了确保我可以稍微修改现有代码:

CALayer *tmpLayer = [CALayer layer];
[tmpLayer addSublayer:self.leftsideLayer];  // CAShapeLayer
[tmpLayer addSublayer:self.rightsideLayer]; // CAShapeLayer
[tmpLayer addSublayer:self.perimeterLayer]; // CAShapelayer
[tmpLayer addSublayer:self.valueLayer];     // CAShapeLayer
[tmpLayer insertSublayer:self.gradientLayer atIndex:0]; // CAGradientLayer + CAShapeLayer (as mask)
[self.layer addSublayer:tmpLayer];
Run Code Online (Sandbox Code Playgroud)

正如所料,这很好.

接下来的步骤是生成所有这些图层的预渲染版本:

//  [self.layer addSublayer:tmpLayer];
    UIGraphicsBeginImageContextWithOptions([self bounds].size, YES, 0.0);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [self drawLayer:tmpLayer inContext:ctx];
    UIImage *renderedImageOfMyself = UIGraphicsGetImageFromCurrentImageContext();
    if (!renderedImageOfMyself) {
        NSLog(@"Well that didn't work");
    }
    UIGraphicsEndImageContext();
    [self.layer setContents:renderedImageOfMyself.CGImage];
Run Code Online (Sandbox Code Playgroud)

结果是屏幕上出现黑色矩形,接下来我尝试了:

// [self.layer setContents:renderedImageOfMyself.CGImage];
[self addSubview:[[UIImageView alloc] initWithImage:renderedImageOfMyself]];
Run Code Online (Sandbox Code Playgroud)

既然这也给了我黑色的矩形,我已经得出结论在屏幕上获得黑色矩形的任何一种方法都可以正常工作;-)但是我不知怎么搞砸了将顶层渲染成位图图形上下文.

我试图摆弄开始新背景的选项部分,YES vs NO,1.0对0.0; 一切都无济于事.

我在以下过程中遗漏了什么:

  • 开始一个新的图形上下文
  • 将我的图层绘制到该上下文中
  • 从该上下文中获取图像

谢谢!

tob*_*jim 9

好吧,我发现了我没做的事情:我的图层从未绘制过它的内容,所以我需要在尝试从中获取图像之前将setNeedsDisplay发送到图层(对于我来说,使用drawLayer:inContext等方法名称对我来说有点奇怪:和renderInContext:)

[tmpLayer setNeedsDisplay];
UIGraphicsBeginImageContextWithOptions([self bounds].size, YES, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[tmpLayer renderInContext:ctx];
renderedImageOfMyself = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.layer setContents:renderedImageOfMyself.CGImage];
Run Code Online (Sandbox Code Playgroud)