objective-c - 使用 CADisplayLink 作为动态频率定时器

标签 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 会导致动画断断续续,因为它并不准确与帧率有关。所以我尝试改用 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 来指示动画的各个帧”,而你一开始就没有这样做。

关于objective-c - 使用 CADisplayLink 作为动态频率定时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23317760/

相关文章:

ios - 当应用程序返回前台时如何恢复核心动画

ios - UIScrollView 损坏并停止使用 OpenGL 渲染滚动(相关 CADisplayLink、NSRunLoop)

iphone - 将选择器加入运行循环 - 是 [NSObject performSelector :withObject:afterDelay:] the way to go?

ios - 在 Cocos2d 中读取 CCB 文件

ios - 如何解析 iOS 中的 SOAP 响应( Objective-C )?

ios - 跳跃的 CADisplayLink 动画

ios - CADisplayLink 无法在模拟器中实现恒定的帧速率

c++ - 使用 objective-c 文件中的 c++ 模板类

iphone - UITableView 重复背景与 2 个图像

ios - 如何使用 for 循环生成按钮数组,然后使用 CADisplayLink 为它们设置动画