В другом тесте анимации ключевых кадров я комбинирую перемещение объекта UIImageView (называемого theImage
) по пути Безье и масштабирование его по мере движения, в результате чего в конце пути изображение увеличивается в 2 раза. Мой исходный код для этого содержит следующие элементы для запуска анимации:
UIImageView* theImage = ....
float scaleFactor = 2.0;
....
theImage.center = destination;
theImage.transform = CGAffineTransformMakeScale(1.0,1.0);
CABasicAnimation *resizeAnimation = [CABasicAnimation animationWithKeyPath:@"bounds.size"];
[resizeAnimation setToValue:[NSValue valueWithCGSize:CGSizeMake(theImage.image.size.height*scaleFactor, theImage.image.size.width*scaleFactor)]];
resizeAnimation.fillMode = kCAFillModeBackwards;
resizeAnimation.removedOnCompletion = NO;
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.path = [jdPath path].CGPath;
pathAnimation.fillMode = kCAFillModeBackwards;
pathAnimation.removedOnCompletion = NO;
CAAnimationGroup* group = [CAAnimationGroup animation];
group.animations = [NSArray arrayWithObjects:pathAnimation, resizeAnimation, nil];
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
group.removedOnCompletion = NO;
group.duration = duration;
group.delegate = self;
[theImage.layer addAnimation:group forKey:@"animateImage"];
Затем, когда анимация завершится, я хочу сохранить изображение в большем размере, поэтому я реализую:
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
theImage.transform = CGAffineTransformMakeScale(scaleFactor,scaleFactor);
}
Это все работает .. вроде. Проблема в том, что в конце анимации theImage
мигает на короткое время - как раз того, чтобы она выглядела плохо. Я предполагаю, что это переход в конце анимации, где я установил преобразование в новый размер.
При экспериментировании с этим я попробовал немного другую форму вышеупомянутого, но все еще получил то же самое мерцание:
CAKeyframeAnimation *resizeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
NSValue* startSizeKey = [NSValue valueWithCATransform3D:CATransform3DScale (theImage.layer.transform, 1.0, 1.0, 1.0)];
NSValue* endSizeKey = [NSValue valueWithCATransform3D:CATransform3DScale (theImage.layer.transform, scaleFactor, scaleFactor, 1.0)];
NSArray* sizeKeys = [NSArray arrayWithObjects:startSizeKey, endSizeKey, nil];
[resizeAnimation setValues:sizeKeys];
....
theImage.transform = CGAffineTransformMakeScale(scaleFactor,scaleFactor);
Но когда я закончил анимацию того же размера, что и оригинал, мерцание НЕТ:
CAKeyframeAnimation *resizeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
NSValue* startSizeKey = [NSValue valueWithCATransform3D:CATransform3DScale (theImage.layer.transform, 1.0, 1.0, 1.0)];
NSValue* middleSizeKey = [NSValue valueWithCATransform3D:CATransform3DScale (theImage.layer.transform, scaleFactor, scaleFactor, 1.0)];
NSValue* endSizeKey = [NSValue valueWithCATransform3D:CATransform3DScale (theImage.layer.transform, 1.0, 1.0, 1.0)];
NSArray* sizeKeys = [NSArray arrayWithObjects:startSizeKey, middleSizeKey, endSizeKey, nil];
[resizeAnimation setValues:sizeKeys];
....
theImage.transform = CGAffineTransformMakeScale(1.0,1.0);
Итак, мой главный вопрос: как я могу анимировать это изображение без мерцания и получить другой размер в конце анимации?
Редактировать 2 марта
Мои первые тесты были с масштабированием изображения. Я просто попытался уменьшить его (IE scaleFactor = 0,4), и мерцание было намного более заметным и намного более очевидным в отношении того, что я вижу. Это была последовательность событий:
- Исходное изображение отображается на экране в начальной точке.
- Когда изображение движется по траектории, оно плавно сжимается.
- Полностью сжатое изображение появляется в конце пути.
- Изображение раскрашивается в исходный размер.
- Изображение окончательно раскрашено в уменьшенный размер.
Так что, похоже, шаг 4 - это мерцание, которое я вижу.
Редактировать 22 марта
Я только что загрузил на GitHub демонстрационный проект, который демонстрирует перемещение объекта по более безликой траектории. Код можно найти на PathMove
Я также писал об этом в своем блоге по адресу Перемещение объектов по более изящному пути в iOS