2013-12-11 4 views
7

Я только что создал ключевых кадров анимации, как это:Keyframe анимация ключ время

[UIView animateKeyframesWithDuration:10 delay:0 options:0 animations:^{ 
    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{ 
     view.alpha = 0; 
    }]; 
} completion:nil]; 

И это CAKeyframeAnimation который создается:

(lldb) po [self.layer animationForKey:@"opacity"] 
<CAKeyframeAnimation:0x10a6364b0; keyTimes = (
    0, 
    "0.1", 
    1 
); values = (
    1, 
    0, 
    0 
); calculationMode = linear; delegate = <UIViewKeyframeAnimationState: 0x10a6358d0>; fillMode = both; timingFunction = easeInEaseOut; duration = 10; keyPath = opacity> 

Вопрос:

вся анимация должна занять 10 секунд, а непрозрачность - 10 * 0,1 = 1 секунда, правильно? Когда я смотрю анимацию, это изменение анимируется дольше 1 секунды.

Почему?

+0

отладки вывод выглядит правильно (от 0 до 1 вторых одушевленного от 100% до 0%, то для Еще 9 секунд ожидают от 0% до 0%). Можете ли вы описать, что видите? Вы меняете непрозрачность где-то еще? Вы не включили медленную анимацию в симуляторе, не так ли? –

+0

Да, CAKeyframeAnimation выглядит совершенно правильно. Я вижу, что непрозрачность меняется на 2 - 2,5 секунды, а не на одну. Я никого не меняю, и Медленная анимация отключена. –

+1

Вы видите то же самое, если сами создаете анимацию ключевого кадра (а не через методы UIView)? –

ответ

8

Причина в том, что функция синхронизации анимации не является линейной.

«Время и пространство относительные понятия.» - Теория относительности

слой и анимация использует иерархическую систему синхронизации, где каждый объект имеет свое локальное время, которое зависит от его родителей и его собственные параметры времени.

Например, анимация имеет функцию синхронизации, которая определяет их стимуляцию. Функции синхронизации по умолчанию для анимации, созданной UIKit, - это облегченная функция синхронизации времени, которая определяет время, которое начинается медленно, ускоряется через середину его продолжительности, а затем замедляется до завершения. Это делает плавные анимации, которые не запускаются или не останавливаются внезапно. Тем не менее, он будет также нравиться ключевыми моментами вашей анимации ключевого кадра, что раздражает, когда вам нужно точное время.

Вы можете отключить время простоты в использовании, передав опцию UIViewAnimationOptionCurveLinear на метод animateKeyframesWithDuration:delay:options:animations:completion:. Я не уверен, предназначено ли это для того, чтобы вам было присвоено значение от UIViewAnimationOptions до UIViewKeyframeAnimationOptions, и в документации об этом ничего не говорится. Может быть лучше (но более многословный) способ встроить блок ключевого кадра анимации внутри стандартного блока анимации, как это:

[UIView animateWithDuration:10 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{ 
    [UIView animateKeyframesWithDuration:0 /*inherited*/ delay:0 options:0 animations:^{ 
     [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:.1 animations:^{ 
      view.alpha = 0; 
     }]; 
    } completion:nil]; 
} completion:nil]; 
+0

Я пропустил два часа, удивляясь, почему эта анимация * $! § не была линейной, даже если я проходил мимо UIViewKeyframeAnimationOptionCalculationModeLinear' (плюс его значение по умолчанию). Спасибо, сэр, спасибо. – AncAinu

+0

Я случайно наткнулся на этот ответ. Я делал это сам в течение многих лет, и это, безусловно, исправляет проблему, хотя я до сих пор не смог точно выяснить, почему мне нужно «взломать» ее таким образом, вставив стандартную анимацию «UIView» вокруг KeyFrameAnimation. Это работает, я знаю, но мое любопытство вызывает у меня :-) +1 для анализа. – Unheilig

+0

@ Николя, похоже, больше не работает на iOS 9. Любая альтернатива? – Xzya

Смежные вопросы