【问题标题】:Optimize QuartzCore Animation with Shadows and Rasterization使用阴影和光栅化优化 QuartzCore 动画
【发布时间】:2013-02-28 23:57:29
【问题描述】:

在我的 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 的图像:

然后是没有shouldRasterize的UIView:

这些屏幕截图都来自同一个 Retina iPad。

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    唯一的缺点是您需要在图层大小发生变化时对其进行编辑。

    【讨论】:

    • 这很好用,但是我应该使用什么方法来更新阴影大小?我想我必须将阴影存储在 ivar 中,然后再通过另一种方法访问它,对吗?
    • @RazorSharp:你为什么要存储它?请记住,如果您更改视图的大小,那么您也需要更新阴影。它显然可以从视图的框架中轻松计算出来。
    • 没错,我的代码是在viewDidLoad 中设置的,我想用某种重绘方法更改它可能是有效的,但我想不出那个方法是什么(我知道在 OSX 上有一个)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2013-05-21
    • 2014-02-18
    • 1970-01-01
    相关资源
    最近更新 更多