3

我一直在使用 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 秒等待淡入/淡出。

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

4

1 回答 1

5

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

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

于 2014-04-26T23:54:58.943 回答