UIView animateWithDuration: 减缓动画帧率

13
我正在使用 CADisplayLink 以每秒60次的速度使用 EAGLView 方法在游戏中绘制帧。
当我调用 UIView animateWithDuration: 时,帧速率会减半,从60降至30 fps,持续时间为动画时间。一旦动画结束,fps会立即回升到60。
我还尝试使用 NSTimer 动画方法而非 CADisplayLink ,但结果相同。
在扬声器图标淡出时按音量按钮也会出现相同的行为,因此可能正在使用 animateWithDuration 。由于我想要在我的应用程序中平稳地处理扬声器图标,这意味着我不能只是重写我的动画代码以使用除 animateWithDuration 之外的其他方法,而是需要找到与其配合的解决方案。
我知道模拟器上有一个选项可以放慢调试中的动画速度,但我在设备上也遇到了这个问题,并且没有启用此类选项。我也尝试使用各种选项 animateWithDuration ,例如线性和用户互动,但都没有改善。
我也知道我可以设计一个引擎,可以使用大幅变化的帧速率。但是,对于游戏来说,高帧速率是理想的解决方式,这不是解决此问题的理想解决方案。
是否有人看到过这个问题或解决过它?

在基于GLKit的应用程序上尝试了音量按钮测试(基于Xcode模板,其中GLKViewController子类为GLKView执行所有绘图),并且注意到没有减速。也许苹果在GLKit中做了一些巫术,可能会对您有所帮助?要么这是iOS 6的问题;还没有在iOS 5上尝试过此应用程序。 - rickster
@rickster 谢谢你。我可以确认这在我的iOS 6 iPad上不会发生。我猜这只是苹果在iOS 6中修复的一个错误。 - Michael Chinen
3个回答

1
解决方法是在CADisplayLink回调期间执行自己的动画和blit。
1)对于音量问题,在角落放置一个小音量图标,或者在用户执行某些预定义的触摸操作时显示它,并提供触摸控件。通过这种输入,您可以使用AVAudioPlayer来改变音量,并避免系统控件。您甚至可以确定用户是否按下了音量按钮,并弹出一些提示说按照您的方式进行操作。这使您远离任何由系统发生的动画。
2)当您想要执行动画时,请在代码中创建一系列图像(无论是在那之前还是之后),并在每个displayLink回调之后将图像blit到屏幕上。

我认为内部处理动画可能是正确的方式。但是,这种处理音量按钮的方式对用户来说仍然不太友好,并且当他们按下按钮时仍会出现帧率下降的情况。此外,如果我使用内部混音器音量,那么这是否意味着最大音量将受限于系统音量设置,从而导致应用内音量显示不一致? - Michael Chinen
我不知道系统音量/应用程序音量的答案 - 你需要进行研究。这只是一个绕过使用侧面按钮的方法。当您的应用程序启动时,甚至可以要求他们增加音量 - 无论如何,他们想要的游戏音量可能与电话铃声等不同(也许是相同的)。如果您可以与他们一起做一些前期工作,并让他们使用屏幕上的音量 - 这将使您的游戏更具响应性。在我看来,你找到绕过系统HUD的方法的几率非常低。 - David H

0

这里有一个描述类似帧率下降的旧线程。在那种情况下,问题的原因是添加了两个或更多半透明精灵,但我猜每当您尝试将几个图层合成在一起时,您可能会做足够的工作来削减帧速率,并且animateWithDuration很可能正是做这种事情的。


-1
要么使用OpenGL,要么使用CoreAnimation。它们不兼容。
为了测试这一点,请移除任何UIView动画,帧速率将达到您期望的水平。添加UIView动画后,帧速率将降至30fps。
您说:
当我调用UIView animateWithDuration:时,帧速率会减半,从60降至30fps,持续时间为动画的时间。一旦动画结束,帧速率立即回升到60。
我不知道为什么你不接受我的答案,这正是当您将UIView动画与没有使用UIView的CA动画组合在一起时发生的事情。

CADisplayLink在OpenGL中运作良好,是许多人使用的EAGLView示例的基础。此外,由于这个问题发生在我触摸扬声器音量按钮时,无论如何都需要处理。 - Michael Chinen
这不是帧率下降的问题。动画文档明确指出,UIView动画锁定在30 FPS,使用CA进行UIView动画时,任何其他动画都将被强制以相同的速率运行。这个问题应该被关闭,因为这是设计上的限制。 - deleted_user
我之前不知道这个,也没有见过,请问你能告诉我哪里有相关的文档吗?我查看了UIView文档并在谷歌上搜寻"30帧每秒的UIView"但是都没有找到。 - Michael Chinen
我已经有一段时间没有在iOS游戏上工作了,但是它还在那里。您不能将UIView动画与任何OpenGL混合并混合帧速率。CA只有一个渲染器,并且UIView动画将其剪辑为30fps。 - deleted_user
1
我无法确定你是否在恶作剧,但是你的个人资料历史记录表明你可能是。你的回答描述了问题,并且你说“文档清楚地说明”,但却无法提供文档链接。 - Michael Chinen
核心动画绝对以每秒60帧的速度运行。如果以30帧每秒的速度运行,操作系统中的任何内容都不会显得流畅。 - jowie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接