Используйте 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
];
}
];
(Точный код не важен, просто общая идея постепенного появления / исчезновения.) Однако, как отмечают многие на Stackru и на различных веб-сайтах, использование 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 ответ
Ссылка на дисплей будет вызывать ваш метод обратного вызова checkTimer
примерно каждые 1/30 секунды. Это все, что он делает. Точное время точно и неизвестно. Отслеживать, сколько времени прошло с того момента, когда он перезвонил вам в последний раз, и решить, означает ли это, что пришло время делать другую анимацию, полностью зависит от вас. Вы должны использовать временную метку отображаемой ссылки, например, чтобы узнать, сколько времени прошло с момента последнего обратного вызова. Вы не делаете это, поэтому ваше время не работает. (Также вы можете тестировать в симуляторе, где CADisplayLink не работает. Вы должны тестировать на устройстве.)
Однако для такого грубого измерения, как "каждые 5 секунд", CADisplayLink является полной тратой. CADisplayLink предназначен для тех случаев, когда вы сами анимируете каждый кадр анимации (то есть вы сами что-то меняете, явно, каждую 1/30 секунды). Это не подходит здесь. Вам все равно, будет ли таймер отключен на 5 секунд, так что ничего страшного. Придерживайтесь вашего текущего кода. Если ваша анимация заикается, выясните, почему; он имеет какое-то отношение к анимации, но не имеет ничего общего с таймером, который, в конце концов, просто говорит "запустить", а затем удаляется. Вы неправильно поняли, что говорят различные посты; они не говорят "не используйте NSTimer", они говорят "не используйте NSTimer, чтобы диктовать отдельные кадры анимации", и вы никогда не делали этого в первую очередь.