使用阴影和光栅化优化QuartzCore动画

时间:2013-02-28 23:57:29

标签: objective-c cocoa-touch animation uiview quartz-core

在我的iOS应用中,我有需要动画,用手势转换,阴影(使用阴影)和编辑。当我在UIView上执行动画和手势时,它非常“迟钝”。 iPhone上的动画效果不是很“迟钝”,但是当使用iPad时,动画几乎没有响应(看起来我的应用程序崩溃了)。我已经使用Instruments测试了我的应用程序,并且应用程序在动画开始之前不占用大量内存/ CPU /功率。我已经在设备和我的Intel i7 8GB iMac上进行了测试,动画在两者上都是“滞后”。

我正在表演的动画并不复杂,只是横跨X轴的翻译。在查看与动画相关的每一行代码后,我发现这些行是问题:

viewer.layer.masksToBounds = NO;
viewer.layer.shadowOffset = CGSizeMake(-1, 1);
viewer.layer.shadowRadius = 3;
viewer.layer.shadowOpacity = 0.3;

上面的代码为视图添加了一个阴影,每当我为它设置动画时它都会滞后(viewer)。如果我使用上面的代码,但我添加以下行动画很好地工作:

viewer.layer.shouldRasterize = YES;

此代码的问题在于严重降低了UIView(viewer)内显示的内容的质量。这是shouldRasterize设置为YES的图像:

UIView with Rasterization

然后没有shouldRasterize的UIView:

UIView without Rasterization

这些截图均来自同一个Retina iPad。

最终问题:如何在带有阴影的UIView上顺畅执行动画(最好使用QuartzCore)?有没有办法在不降低内容质量的情况下栅格化内容?

1 个答案:

答案 0 :(得分:3)

CALayer上的阴影属性在制作动画时效率非常低,因为它需要根据图层的内容重新计算每个帧上的阴影。幸运的是,昂贵的部分是阴影路径计算,所以如果您只是创建一个表示内容形状的CGPath并将其分配给layer.shadowPath,那么性能将会飙升。

由于您的图层似乎完全填充了不透明数据,因此shadowPath非常简单:

layer.shadowPath = [UIBezierPath bezierPathWithRect:(CGRect){CGPointZero, layer.bounds.size}].CGPath;

唯一的缺点是,只要图层大小发生变化,您就需要编辑它。