После долгих поисков и разговоров с гуру разработки под iOS выясняется, что QA1673 не помогает, когда дело доходит до паузы, фонового изображения и перемещения на передний план. Мои эксперименты даже показывают, что методы делегирования, которые запускаются из анимации, такие как animationDidStop
, становятся ненадежными.
Иногда они стреляют, иногда нет.
Это создает много проблем, потому что это означает, что вы не только смотрите на другой экран, который вы видели, когда вы делали паузу, но и последовательность событий, находящихся в движении в данный момент, может быть нарушена.
Мое решение до сих пор было следующим:
Когда начинается анимация, я получаю время начала:
mStartTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
Когда пользователь нажимает кнопку паузы, я удаляю анимацию из CALayer
:
[layer removeAnimationForKey:key];
Я получаю абсолютное время, используя CACurrentMediaTime()
:
CFTimeInterval stopTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
Используя mStartTime
и stopTime
, я вычисляю время смещения:
mTimeOffset = stopTime - mStartTime;
Я также установил значения модели объекта равными presentationLayer
. Итак, мой stop
метод выглядит так:
//--------------------------------------------------------------------------------------------------
- (void)stop
{
const CALayer *presentationLayer = layer.presentationLayer;
layer.bounds = presentationLayer.bounds;
layer.opacity = presentationLayer.opacity;
layer.contentsRect = presentationLayer.contentsRect;
layer.position = presentationLayer.position;
[layer removeAnimationForKey:key];
CFTimeInterval stopTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
mTimeOffset = stopTime - mStartTime;
}
При возобновлении я пересчитываю то, что осталось от приостановленной анимации на основе mTimeOffset
. Это немного грязно, потому что я использую CAKeyframeAnimation
. Я выясняю, какие ключевые кадры выдающиеся, основываясь на mTimeOffset
. Кроме того, я принимаю во внимание, что пауза могла произойти в середине кадра, например на полпути между f1
и f2
. Это время вычитается из времени этого ключевого кадра.
Затем я снова добавляю эту анимацию к слою:
[layer addAnimation:animationGroup forKey:key];
Еще одна вещь, которую нужно помнить, это то, что вам нужно будет проверить флаг в animationDidStop
и удалить анимированный слой из родительского элемента только с removeFromSuperlayer
, если флаг YES
. Это означает, что слой все еще виден во время паузы.
Этот метод кажется очень трудоемким. Это работает, хотя! Я бы хотел просто сделать это, используя QA1673 . Но в настоящее время для фоновой работы это не работает, и это, кажется, единственное решение.