使用CADisplayLink作为动态频率计时器

时间:2014-04-26 23:46:52

标签: objective-c cadisplaylink

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

[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会导致口吃动画,因为它不是&# 39; t精确地与帧速率相关联。所以我尝试使用CADisplayLink:

// 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秒等待淡入/淡出。

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

1 个答案:

答案 0 :(得分:4)

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

然而,对于总计为“每5秒钟”的测量,CADisplayLink完全是浪费。 CADisplayLink适用于您自己动画动画的每一帧(即,您每隔1/30秒显式更改一些内容,您自己)。这不合适。你不关心计时器是否相对于5秒钟只是一秒钟的一小部分,所以没有什么大不了的。坚持使用您当前的代码。如果你的动画是口吃,找出原因;它与动画有关,但它与计时器没有关系,毕竟只是说“开始”然后退休。你误解了各个帖子的内容;他们没有说“不要使用NSTimer”,他们说“不要使用NSTimer来决定动画的各个帧”,而你从来没有这样做过。