使用 CADisplayLink 作为动态频率定时器 [英] Use CADisplayLink as dynamic frequency timer

查看:90
本文介绍了使用 CADisplayLink 作为动态频率定时器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 NSTimer 根据用户设置的频率淡入/淡出我的应用程序中的一些图像.例如,如果用户将频率设置为 5 秒,那么每 5 秒将执行以下代码:

I've been using NSTimer to fade-in/fade-out some images in my app based on user-set frequency. For example, if user set frequency to 5 seconds, then every 5 seconds the following code will execute:

[UIView animateWithDuration:someInterval
                          delay:0
                        options:UIViewAnimationCurveEaseInOut
                     animations:
                        ^{
                            // UI alpha = ... code here
                        }
                     // off...
                     completion:^(BOOL finished){


                         [UIView animateWithDuration:someOtherInterval
                                               delay:yetAnotherValue
                                             options:UIViewAnimationCurveEaseInOut
                                          animations:
                                            ^{
                                                // UI alpha = ... code here
                                            }
                                          completion:nil
                          ];
                     }
     ];

(确切的代码并不重要,只是淡入/淡出的总体思路.)但是,正如 StackOverflow 和各种网站上的许多人指出的那样,使用 NSTimer 会导致动画断断续续,因为它并不准确与帧率有关.所以我尝试改用 CADisplayLink:

(The exact code isn't important, just the overall idea of fade-in/fade-out.) However, as many on StackOverflow and various websites point out, using NSTimer results in stuttering animations because it isn't precisely tied to the frame rate. So I tried to use CADisplayLink instead:

// in viewDidAppear:
timer_count = 0;
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(checkTimer)];
displayLink.frameInterval = 1;
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

-(void)checkTimer
{
    timer_count++;
    if(timer_count >= 1500)
    {
        [self doFadeInOutAnimation];
        timer_count = 0;
    }
}

但这并没有达到预期的效果;图像只是以非常快的速度连续显示,而不是每 5 秒等待一次淡入/淡出.

This isn't having the desired effect though; the images are just displayed in very rapid succession instead of waiting to fade-in/out every 5 seconds.

知道什么是正确的方法吗?

Any idea what's the proper way to do it?

推荐答案

显示链接将大约每 1/30 秒调用一次您的回调方法 checkTimer.这就是它所做的一切.确切的时间是不准确和未知的.跟踪自它上次给您回电以来已经过去了多长时间,并决定这是否意味着是时候做另一个动画了,完全取决于您.例如,您必须使用显示链接的时间戳来了解自上次回调以来已经过去了多长时间.你没有这样做,所以你的时机不对.(您也可能在模拟器中进行测试,其中 CADisplayLink 不起作用.您必须在设备上进行测试.)

The display link is going to call your callback method checkTimer approximately every 1/30th of a second. That's all it does. The exact timing is inexact and unknown. Keeping track of how much time has elapsed since the last time it called you back, and deciding whether this means it's time to do another animation, is completely up to you. You have to use the display link's timestamp, for example, to know just how long it's been since the last callback. You aren't doing that so your timing is off. (Also you may be testing in the Simulator, where CADisplayLink doesn't work. You have to test on the device.)

但是,对于像每 5 秒"这样粗略的测量,CADisplayLink 完全是浪费.CADisplayLink 适用于当您自己为动画的每一帧设置动画时(也就是说,您正在改变某些东西,自己,明确地,每 1/30 秒).这里不合适.您不在乎计时器相对于 5 秒是否关闭了几分之一秒,因此没什么大不了的.坚持使用您当前的代码.如果您的动画卡顿,请找出原因;它与动画有关,但与计时器无关,毕竟它只是说开始"然后退出.你误解了各种帖子的意思;他们不会说不要使用 NSTimer",而是说不要使用 NSTimer 来指定动画的各个帧",而您一开始就没有这样做.

However, for a measurement as gross as "every 5 seconds", CADisplayLink is a complete waste. CADisplayLink is intended for when you yourself are animating every frame of the animation (that is, you are changing something, yourself, explicitly, every 1/30th of a second). That's not appropriate here. You don't care whether the timer is a fraction of a second off with respect to 5 seconds, so there's no big deal. Stick with your current code. If your animation is stuttering, figure out why; it has something to do with the animation, but it has nothing to do with the timer, which after all is merely saying "start" and then retiring. You have misunderstood what the various posts say; they don't say "don't use NSTimer", they say "don't use NSTimer to dictate the individual frames of an animation", and you were never doing that in the first place.

这篇关于使用 CADisplayLink 作为动态频率定时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆