是否可以在 iOS 上控制帧速率

Posted

技术标签:

【中文标题】是否可以在 iOS 上控制帧速率【英文标题】:is it possible to control frame rate on iOS 【发布时间】:2012-05-16 12:19:08 【问题描述】:

我通过设置 UIView 的 origin 属性来为在屏幕上弹跳的球设置动画,但我发现球的移动并不顺畅。我检查了调用 drawInRect 的频率,它是 30 次/秒,我认为这不足以使快速的球运动平滑。

我的问题是,是否可以要求系统以 60fps 刷新/重绘屏幕?你能在 OpenGL 中做同样的事情吗?

【问题讨论】:

如果您使用 UIImage 的 -drawInRect 来刷新球的位置,请注意核心图形重绘是一项非常昂贵的操作,而不是您想要的任何动画。绘制对象一次,之后仅移动其包含的视图或图层。 【参考方案1】:

您可以考虑设置显示链接功能。这将允许您为通过系统的每个绘制调用(或每个特定数量的帧)触发一个方法。你要处理的类是CADisplayLink,here是教程。如果您的动画仍然不够快,那么您的动画将永远不会看起来流畅;)。

【讨论】:

【参考方案2】:

你不需要改变 ios 的 fps 来让你的动画正确。你只需要在你的代码中改变它,你可以使用 NSTimer (An Example):-

在一些动画上初始化一个计时器:-

    float theInterval = 1.0/30.0;//Here you can set the frame rate , now set on 30
    [NSTimer scheduledTimerWithTimeInterval:theInterval target:self
        selector:@selector(animateView:) userInfo:nil repeats:YES];

    - (void)animateView:(NSTimer *)theTimer 
    
    //    your animation block here....
    Something like..
    view.center = CGPointMake(view.center.x+viewMovement.x,
                    view.center.y+viewMovement.y);

        BOOL collision = view.center.y >= view2.center.y - 16 &&
        view.center.y <= view2.center.y + 16 &&
        view.center.x > view2.center.x - 32 &&
        view.center.x < view2.center.x + 32;

    if(collision)
        viewMovement.y = -viewMovement.y


这只是一个例子,相应地实现你的逻辑。

【讨论】:

这是一个非常糟糕的建议。在绘制代码结束时,系统会阻塞渲染线程,直到显示刷新,所以这个计时器要么堆积绘制命令,要么添加卡顿。 切勿使用系统计时器来控制动画!您应该始终测量帧之间的时间,并相应地推进动画。 我只是举了一个例子,顺便说一句,我在上面做了一个游戏,使用这个代码就像魅力一样,你可以根据你的情况让计时器失效......这里不需要投票.. 是吗.. NSthread 会是个好主意 2... 除了 datenwolf 所说的之外,如果您要使用某种计时器来刷新显示,您确实应该使用 CADisplayLink。 NSTimer 与显示刷新不同步,如 CADisplayLink,使用 NSTimer 将无法获得最流畅的显示刷新。

以上是关于是否可以在 iOS 上控制帧速率的主要内容,如果未能解决你的问题,请参考以下文章

iOS上的opencv cvGrabFrame帧速率?

SDL 帧速率上限实施

控制 gstreamer 源插件的输出速率

# WPF动画速率效果

openGL 中的帧速率和绘制流程

如何确定 html 视频元素的预期帧速率