我的UIView的子类广泛使用子层来构建复杂的图像。屏幕上有多达30个这样的视图,在iPad 2上,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)
屏幕渲染非常完美。但是由于动画开始滞后,我准备了这段代码,用于构建临时图层,目的是将临时图层渲染为位图。第一步是确保我可以稍微修改现有代码:
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];
正如预期的那样,这很好。
接下来的步骤是生成所有这些图层的预渲染版本:
// [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];
结果是屏幕上出现黑色矩形,接下来我尝试了:
// [self.layer setContents:renderedImageOfMyself.CGImage];
[self addSubview:[[UIImageView alloc] initWithImage:renderedImageOfMyself]];
因为这也给了我黑色的矩形,我已经得出结论,在屏幕上获得黑色矩形的任何一种方法都可以正常工作;-)但是我有点搞砸了将顶层渲染成位图图形上下文。
我试图摆弄开始新背景的选项部分,YES vs NO,1.0对0.0;一切都无济于事。
我在以下过程中遗漏了什么:
谢谢!
答案 0 :(得分: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];
答案 1 :(得分:2)
干得好但有时在iOS 6上无法用于奇怪的指针工作。
我希望这能帮助将来的某个人:)(Todd Yandell在stackoverflow上发现的部分代码)
UIGraphicsBeginImageContextWithOptions([tmpLayer frame].size, YES, 0.0);
[tmpLayer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();