Периодическая ошибка fillMode=kCAFillModeForwards при использовании CAKeyframeAnimation с путем

У меня периодически возникает проблема, когда я перемещаю UIImageView по экрану с помощью CAKeyframeAnimation. Я хочу, чтобы позиция UIImageView оставалась там, где заканчивается анимация, когда она завершена. Эта ошибка возникает только для определенных начальных и конечных точек. Когда я использую случайные точки, он работает правильно большую часть времени, но примерно в 5-15% случаев он дает сбой и возвращается к положению перед анимацией. Проблема возникает только при использовании CAKeyframeAnimation с использованием свойства path. Если я использую свойство values, ошибка не появляется. Я устанавливаю removeOnCompletion = NO и fillMode = kCAFillModeForwards. Я разместил ссылку на тестовый Xcode ниже. Вот мой код для настройки анимации. У меня есть свойство usePath. Когда это ДА, появляется ошибка. Когда я устанавливаю для usePath значение NO, ошибка привязки не возникает. В этом случае я использую путь, представляющий собой простую линию, но как только я решу эту ошибку с помощью простого пути, я буду использовать более сложный путь с кривыми в нем.

// create the point        
CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
if (self.usePath) {
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, startPt.x, startPt.y);
    CGPathAddLineToPoint(path, NULL, endPt.x, endPt.y);
    moveAnimation.path = path;
    CGPathRelease(path);    
} else {
    moveAnimation.values = [NSArray arrayWithObjects:
                            [NSValue valueWithCGPoint:startPt],
                            [NSValue valueWithCGPoint:endPt],
                            nil];
}
moveAnimation.calculationMode = kCAAnimationPaced;
moveAnimation.duration = 0.5f;
moveAnimation.removedOnCompletion = NO;
// leaves presentation layer in final state; preventing snap-back to original state
moveAnimation.fillMode = kCAFillModeForwards; 
moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
// moveAnimation.delegate = self;    

// start the animation
[ball.layer addAnimation:moveAnimation forKey:@"moveAnimation"];

Чтобы просмотреть мой тестовый проект, перейдите в тестовый проект (http://www.24x7digital.com/downloads/PathFillModeBug.zip)

Нажмите кнопку «Переместить мяч», чтобы начать анимацию мяча. Я жестко запрограммировал начальную и конечную точки, из-за чего ошибка возникает каждый раз. Используйте переключатель, чтобы изменить usePath на YES или NO. Когда для usePath установлено значение YES, вы увидите ошибку возврата. Когда usePath имеет значение NO, вы не увидите ошибку возврата.

Я использую SDK 3.1.3, но я видел эту ошибку и при использовании SDK 3.0, и я видел ошибку на Sim и на моем iPhone.

Любая идея о том, как это исправить или если я делаю что-то не так, приветствуется. Спасибо, Марк.


person Mark24x7    schedule 12.03.2010    source источник


Ответы (1)


Связавшись с [email protected], они подтвердили, что в Core Animation есть ошибка в отношении kCAFillModeForwards с путями. Они сказали мне подать отчет об ошибке, что я и сделал (идентификатор проблемы: 7797921).

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

// start the animation
[ball.layer addAnimation:moveAnimation forKey:@"moveAnimation"];
ball.layer.position = endPt;

Но в моем реальном приложении я устанавливаю rotateMode = kCAAnimationRotateAuto, чтобы вращение объектов по оси z обновлялось, чтобы оно оставалось касательным к пути. Поэтому, когда происходит привязка, вращение ротацииMode z теряется. Они сказали мне установить вращение явно в animationDidStop:finished: вот так:

[ball.layer setValue:[NSNumber numberWithDouble:-M_PI/2.0] forKeyPath:@"transform.rotation.z"];

Это не решает проблему полностью, потому что иногда я получаю мерцание обратного поворота привязки, а затем корректирующего поворота. Я надеюсь, что они исправят ошибку fillMode = kCAFillModeForwards с путями.

person Mark24x7    schedule 26.03.2010
comment
Привет, mark24x7, именно с этим сейчас и сталкиваюсь. Я сделал с вашим обходным путем, кажется, все в порядке. И сброс в animationDidStop:finished: действительно вызывает мерцание. Кстати, я ориентируюсь на ios 5 или выше и разрабатываю на ios 6.0SDK. - person David; 01.12.2012