我将钟表臂指向12点钟到当前时间。如果是,11点,我想让手臂顺时针旋转到11点位置。但当然如果我使用:
CGAffineTransform rotation = CGAffineTransformMakeRotation(2*M_PI*11/12);
[UIView animateWithDuration:3.0
animations:^{
clockArm.transform = rotation;
}];
旋转逆时针旋转。我试过了:
CGFloat angle = 2*M_PI*11/12;
CGAffineTransform firstRotation = CGAffineTransformMakeRotation(M_PI-0.001);
CGFloat firstRotationTime = 3.0*(M_PI/angle);
CGAffineTransform secondRotation = CGAffineTransformMakeRotation(angle);
CGFloat secondRotationTime = 3.0 - firstRotationTime;
[UIView animateWithDuration:firstRotationTime
delay:0.0
options:UIViewAnimationCurveLinear
animations:^{
self.clockArm1.transform = firstRotation;
}
completion:^(BOOL finished) {
[UIView animateWithDuration:secondRotationTime
delay:0.0
options:UIViewAnimationCurveLinear
animations:^{
self.clockArm1.transform = secondRotation;
}
completion:^(BOOL finished){
}];
}];
动画确实是顺时针方向,但它很不稳定 - 动画似乎仍在为第一个动画做一个UIViewAnimationEaseInOut。我做错了什么,或者有其他方法可以实现我想要的目标吗?
答案 0 :(得分:7)
您可以使用CATransaction
的完成块在动画结束时设置视图的旋转属性。以下函数在我的测试用例中起作用:
- (void) rotateViewAnimated:(UIView*)view
withDuration:(CFTimeInterval)duration
byAngle:(CGFloat)angle
{
[CATransaction begin];
CABasicAnimation *rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.byValue = [NSNumber numberWithFloat:angle];
rotationAnimation.duration = duration;
rotationAnimation.removedOnCompletion = YES;
[CATransaction setCompletionBlock:^{
view.transform = CGAffineTransformRotate(view.transform, angle);
}];
[view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
[CATransaction commit];
}
你像
一样使用它[self rotateViewAnimated:self.clockArm1 withDuration:3.0 byAngle:2*M_PI*11./12.];
答案 1 :(得分:3)
感谢@Martin R的接受答案。我编辑了一下:
我替换了这一行
rotationAnimation.removedOnCompletion = YES;
这两行:
rotationAnimation.removedOnCompletion = NO;
rotationAnimation.fillMode = kCAFillModeForwards;
然后,在CompletionBlock中,我又添加了一行:
[view.layer removeAllAnimations];
所以,代码最终成为:
- (void) rotateViewAnimated:(UIView*)view
withDuration:(CFTimeInterval)duration
byAngle:(CGFloat)angle
{
[CATransaction begin];
CABasicAnimation *rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.byValue = [NSNumber numberWithFloat:angle];
rotationAnimation.duration = duration;
// changed by me
rotationAnimation.removedOnCompletion = NO;
rotationAnimation.fillMode = kCAFillModeForwards;
[CATransaction setCompletionBlock:^{
view.transform = CGAffineTransformRotate(view.transform, angle);
// added by me
[view.layer removeAllAnimations]; // this is important
}];
[view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
[CATransaction commit];
}
我的推荐来自:
1,https://stackoverflow.com/a/3586433/2481444
2,After rotating a CALayer using CABasicAnimation the layer jumps back to it's unrotated position
答案 2 :(得分:1)
正如评论中所述,试试这个iphone UIImageView rotation 或UIView Infinite 360 degree rotation animation?
#import <QuartzCore/QuartzCore.h>
- (void) runSpinAnimationWithDuration:(CGFloat) duration;
{
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 2.0 /* full rotation*/ * rotations * duration ];
rotationAnimation.duration = duration;
rotationAnimation.cumulative = YES;
rotationAnimation.repeatCount = 1.0;
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[myView.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}