目标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会导致动画断断续续,因为它与帧速率没有精确的联系。所以我试着用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/30秒调用一次回调方法checkTimer。这就是它所做的一切。确切的时间是不准确和未知的。跟踪自上次它给你回电话以来已经过去了多少时间,并决定这是否意味着是时候制作另一个动画了,这完全取决于你。例如,您必须使用显示链接的时间戳来了解自上次回调以来的时间。你没有这么做,所以你的时机不对。(你也可能在模拟器中测试,CADisplayLink不起作用。你必须在设备上测试。)

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

最新更新