【问题标题】:Use CADisplayLink as dynamic frequency timer使用 CADisplayLink 作为动态频率定时器
【发布时间】:2014-04-26 23:46:51
【问题描述】:

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

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

【问题讨论】:

    标签: objective-c cadisplaylink


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢@matt。我查看了之前的 NSTimer 设置,它适用于所有淡入/淡出,除了执行 viewDidAppear 时的 first 淡入/淡出。每次调用 viewDidAppear 时我都会执行 [timer fire],但是当这种情况发生时,淡入很好,但淡出会过早地结结/切断。知道为什么会这样吗?
    • 也许,但那将是一个不同的问题。不要试图将问题叠加在一起。如果您还有其他问题,请提出其他问题!我已尝试回答您确实提出的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多