Pet*_*r M 6 scaling flicker uiimageview cakeyframeanimation ios
在关键帧动画的另一个测试中,我正在组合theImage沿着贝塞尔曲线路径移动UIImageView(被调用)并在移动时缩放它,导致路径末端的图像大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"];
Run Code Online (Sandbox Code Playgroud)
然后,当动画完成时我想保留更大尺寸的图像,所以我实现:
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
theImage.transform = CGAffineTransformMakeScale(scaleFactor,scaleFactor);
}
Run Code Online (Sandbox Code Playgroud)
这一切都有效..有点儿.问题在于动画结束时会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);
Run Code Online (Sandbox Code Playgroud)
但当我以与原版相同的大小结束动画时,没有闪烁:
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);
Run Code Online (Sandbox Code Playgroud)
所以我的大问题是如何在没有闪烁的情况下为此图像设置动画,并在动画结束时以不同的大小结束?
编辑3月2日
我最初的测试是缩放图像.我只是尝试缩小它(IE scaleFactor = 0.4)并且闪烁更加明显,而且我所看到的更加明显.这是一系列事件:
所以似乎第4步就是我所看到的闪烁.
编辑3月22日
我刚刚向GitHub上传了一个演示项目,该项目展示了沿着bezier路径移动对象的过程.代码可以在PathMove找到
我还在我的博客中写了一篇关于在iOS中沿着bezier路径移动对象的文章
使用Core Animation为视图的图层设置动画可能会很棘手.有几件事令人困惑:
在图层上设置动画不会更改图层的属性.相反,它会更改"表示层"的属性,只要应用动画,它就会替换屏幕上的原始"模型层".
更改图层的属性通常会向图层添加隐式动画,并将属性名称作为动画的键.因此,如果要显式动画属性,通常需要将属性设置为其最终值,然后添加其键为属性名称的动画,以覆盖隐式动画.
视图通常会在其图层上禁用隐式动画.它还以其他有些神秘的方式在其层的属性上进行修复.
另外,让视图的边界变焦以进行缩放是令人困惑的,但最后切换到缩放变换.
我认为最简单的方法就是尽可能地使用UIView动画方法,并且只为关键帧动画引入Core Animation.在您UIView添加自己的动画后,可以将关键帧动画添加到视图的图层,并且关键帧动画将覆盖添加的动画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];
}];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8000 次 |
| 最近记录: |