gpt4 book ai didi

iOS CAKeyFrameAnimation 动画结束时缩放闪烁

转载 作者:可可西里 更新时间:2023-11-01 03:37:57 27 4
gpt4 key购买 nike

在另一个关键帧动画测试中,我结合了沿着贝塞尔曲线路径移动 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 日

我最初的测试是放大图像。我只是尝试缩小它 (IE scaleFactor = 0.4) 并且闪烁更加明显,并且就我所看到的而言更加明显。这是事件的顺序:

  1. 原始尺寸的图像绘制在屏幕上的起始位置。
  2. 随着图像沿着路径移动,它会平滑地缩小。
  3. 完全缩小的图像到达路径的尽头。
  4. 然后以原始大小绘制图像。
  5. 图像最终以缩小后的尺寸绘制。

所以我看到的闪烁似乎是第 4 步。


编辑 3 月 22 日

我刚刚向 GitHub 上传了一个演示项目,展示了对象沿贝塞尔曲线路径的移动。代码可以在 PathMove 找到

我也在我的博客 Moving objects along a bezier path in iOS 上写过它

最佳答案

使用 Core Animation 为 View 的层设置动画可能会很棘手。有几件事让它变得困惑:

  • 在图层上设置动画不会更改图层的属性。相反,只要应用了动画,它就会更改“表示层”的属性,该“表示层”会替换屏幕上的原始“模型层”。

  • 更改层的属性通常会向层添加隐式动画,并将属性名称作为动画的键。因此,如果您想显式地为某个属性设置动画,您通常需要将该属性设置为它的最终值,然后添加一个以属性名称为键的动画,以覆盖隐式动画。

  • View 通常会在其图层上禁用隐式动画。它还以其他有些神秘的方式处理其层的属性。

此外,令人困惑的是,您为 View 的边界设置动画以将其放大,但最后切换到缩放转换。

我认为做你想做的最简单的方法是尽可能使用UIView动画方法,并且只为关键帧动画引入Core Animation。在让 UIView 添加自己的动画后,您可以将关键帧动画添加到 View 层,并且您的关键帧动画将覆盖 UIView 添加的动画。

这对我有用:

- (IBAction)animate:(id)sender {
UIImageView* theImage = self.imageView;
CGFloat scaleFactor = 2;
NSTimeInterval duration = 1;

UIBezierPath *path = [self animationPathFromStartingPoint:theImage.center];
CGPoint destination = [path currentPoint];

[UIView animateWithDuration:duration animations:^{
// UIView will add animations for both of these changes.
theImage.transform = CGAffineTransformMakeScale(scaleFactor, scaleFactor);
theImage.center = destination;

// Prepare my own keypath animation for the layer position.
// The layer position is the same as the view center.
CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
positionAnimation.path = path.CGPath;

// Copy properties from UIView's animation.
CAAnimation *autoAnimation = [theImage.layer animationForKey:@"position"];
positionAnimation.duration = autoAnimation.duration;
positionAnimation.fillMode = autoAnimation.fillMode;

// Replace UIView's animation with my animation.
[theImage.layer addAnimation:positionAnimation forKey:positionAnimation.keyPath];
}];
}

关于iOS CAKeyFrameAnimation 动画结束时缩放闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9500968/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com