在另一个关键帧动画测试中,我将移动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);
我的重要问题是如何在没有闪烁的情况下动画化此图像,并在动画结束时得到不同的大小?
编辑于3月2日
我的初始测试是将图像放大。我尝试了缩小它(即scaleFactor = 0.4),闪烁更加明显,我看到的情况也更加明显。以下是事件的顺序:
- 在起始位置屏幕上绘制原始大小的图像。
- 随着图像沿路径移动,它平滑地缩小。
- 完全缩小的图像到达路径的末端。
- 然后以其原始大小绘制图像。
- 最后以其缩小的大小绘制图像。
因此,似乎是步骤4导致了我所看到的闪烁。
3月22日更新
我刚刚在GitHub上上传了一个演示项目,展示了沿着贝塞尔曲线移动对象的方法。代码可以在PathMove找到。
我还在我的博客中写了一篇关于这个主题的文章,链接为iOS中沿着贝塞尔曲线移动对象
kCAAnimationRotateAuto
并解释了如何避免旋转开始和结束时的闪烁。我还在github上放了一个测试项目:https://github.com/mayoff/stackoverflow-kCAAnimationRotateAuto。 - rob mayoff