我的 UIView 动画很生涩 - 如何优化以下代码?
Posted
技术标签:
【中文标题】我的 UIView 动画很生涩 - 如何优化以下代码?【英文标题】:My UIView animation is jerky - how can I optimize the following code? 【发布时间】:2012-01-14 01:22:25 【问题描述】:在模拟器上,我的动画方法运行流畅。不幸的是,它在 iPhone 4 上运行似乎非常生涩。
我不能 100% 确定制作动画的最佳和最快方法 - 因此,如果我能优化或完全修改我的代码以加快动画速度,我将不胜感激!
注意事项:
它已经在主线程上,所以这是否会使 'dispatch_async(dispatch_get_main_queue())' 调用无关或无用?
有没有办法预先缓冲这个动画?
有没有办法准确地查看代码的哪一部分造成了大部分的减速?
extensionView.subviews 中只有大约 3 或 4 个视图。
我用 -Os 编译过。
- (void)extendWithAnimation:(BOOL)animated;
isExtended = YES;
extensionView.hidden = NO;
topShadowView.hidden = NO;
topShadowView.frame = CGRectMake(0, defaultHeight, topShadowView.frame.size.width, topShadowView.frame.size.height);
topShadowView.layer.bounds = CGRectMake(0, 0, topShadowView.frame.size.width, 0);
extensionView.frame = CGRectMake(0, defaultHeight - 8, DEVICE_WIDTH, extensionHeight + 8);
extensionView.layer.bounds = CGRectMake(0, 0, DEVICE_WIDTH, 0);
for (UIView *view in extensionView.subviews)
view.transform = CGAffineTransformMakeTranslation(0, -(extensionHeight+8));
dispatch_async(dispatch_get_main_queue(), ^
if (animated)
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3];
[UIView setAnimationDelegate:self];
extensionView.layer.bounds = CGRectMake(0, 0, DEVICE_WIDTH, extensionHeight + 8);
topShadowView.layer.bounds = CGRectMake(0, 0, topShadowView.frame.size.width, extensionHeight + 8);
for (UIView *view in extensionView.subviews)
view.transform = CGAffineTransformIdentity;
if (animated)
[UIView commitAnimations];
);
解决方案:
已解决(感谢 Aaron!)。
渲染的阴影会扼杀动画!如果您打算制作动画,请不要使用任何核心图形阴影属性 - 在我的例子中,只有几个阴影将帧速率降低了三倍。
【问题讨论】:
CALayer 阴影绘制性能如果为图层指定 shadowPath 会大大提高,您可以在删除所有代码之前尝试一下... @jrturton 很有趣,不幸的是,这对于我的问题所在的 UITextView 并不起作用。但对于其他有类似问题的人来说,这听起来很不错! 【参考方案1】:-
好吧,如果代码已经在主队列中,那么使用 dispatch_async 只会产生开销。
我不知道这是否会有所帮助(我有点怀疑),但您可以尝试使用
[UIView animateWithDuration:.3 animations: code... ];
在我过去尝试处理阴影时,它们往往会对性能造成很大影响。您可能会考虑单独保留阴影和图层,而是创建一个可调整大小的阴影 PNG,您可以在 UIImageView 中使用它,该 UIImageView 放置在您想要阴影的视图后面。
【讨论】:
谢谢!阴影视图实际上是您建议的 PNG,尽管一些涉及的子视图已经渲染了阴影,所以也许这就是问题所在 - 将很快尝试 :) 我同意 dispatch_async() 是不必要的,但是 GCD 真的非常快;如果这会增加任何有意义的延迟,我会感到惊讶。 @Jordan 可能,我首先要移除阴影,看看它的表现如何。如果是这样,那么您可以将它们重新添加为 PNG,然后重试。 我也同意 GCD 速度很快,性能损失应该可以忽略不计。 GCD 可能不会增加延迟,但绝对没有意义。它所做的只是将动画从开始延迟 1/60 秒。你不能在后台线程上做 UIView 动画,你不应该尝试。【参考方案2】:通过 Instruments 运行您的代码(从 Time Profiler 开始)。动画期间哪些调用占用的时间最多?
一旦您对其进行了分析,还可以通过 Core Animation 工具运行它,并启用屏幕外渲染和非透明内容的着色。这将有助于隔离常见的图形问题。
我还注意到你提到了阴影。如果您使用的是 CALayer 阴影属性,那可能会影响您的性能。但我们需要更多信息才能真正确定这一点。
【讨论】:
以上是关于我的 UIView 动画很生涩 - 如何优化以下代码?的主要内容,如果未能解决你的问题,请参考以下文章