Rotating a CALayer from a start angle - iphone

I want to rotate a layer continuously using byValue, but I can't make it work correctly.
I want to rotate by 6 degrees every second, to have a full rotation in 60 seconds.
If the initial rotation of the layer is 0, everything is OK.
The problem is when I try to set an initial fromValue. If I set the fromValue to 90 degrees, the animation will rotate from 90 to 90+6, then jump to 90+(90+6), animate, and jump again.
Any idea?
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.fromValue = [NSNumber numberWithDouble:M_PI_2];
animation.byValue = [NSNumber numberWithDouble:6.0f*M_PI/180.0f];
animation.toValue = nil;
animation.fillMode = kCAFillModeForwards;
animation.cumulative = YES;
animation.additive = NO;
animation.repeatCount = 10000;
animation.removedOnCompletion = YES;
animation.duration = 1.0;
[myLayer addAnimation:animation forKey:#"transform"];

This works for me:
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath: #"transform"];
CATransform3D transform = CATransform3DMakeRotation (DegreesToRadians (90), 0, 0, 1);
animation.toValue = [NSValue valueWithCATransform3D: transform];
animation.duration = 60;
animation.cumulative = NO;
animation.repeatCount = 10000;
animation.removedOnCompletion = YES;

Related

iphone view animation problem

I'm using following code to animate a view. It basically rotates the view by 225 degrees angle.
[viewToOpen.layer removeAllAnimations];
viewToOpen.hidden = NO;
viewToOpen.userInteractionEnabled = NO;
if (viewToOpen.layer.anchorPoint.x != 0.0f) {
viewToOpen.layer.anchorPoint = CGPointMake(0.0f, 0.5f);
viewToOpen.center = CGPointMake(viewToOpen.center.x - viewToOpen.bounds.size.width/2.0f, viewToOpen.center.y);
}
CABasicAnimation *transformAnimation = [CABasicAnimation animationWithKeyPath:#"transform"];
transformAnimation.removedOnCompletion = NO;
transformAnimation.duration = duration;
transformAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
CATransform3D endTransform = CATransform3DMakeAffineTransform(CGAffineTransformMakeRotation(225));
transformAnimation.toValue = [NSValue valueWithCATransform3D:endTransform];
CAAnimationGroup *theGroup = [CAAnimationGroup animation];
theGroup.delegate = self;
theGroup.duration = duration;
[theGroup setValue:[NSNumber numberWithInt:viewToOpen.tag] forKey:#"viewToOpenTag"];
theGroup.animations = [NSArray arrayWithObjects:transformAnimation, nil];
theGroup.removedOnCompletion = NO;
[viewToOpen.layer addAnimation:theGroup forKey:#"flipViewOpen"];
But the problem is that, at the end of animation, the view is coming back to original position. I would like to keep the view in same position even after animation completes. How can I do it?
I believe you're experiencing the same issue as can be seen in this question and this one. You either need to set fillMode to kCAFillModeForwards or set the transform of the layer when the animation has been completed.

How to rotate this view to a specific value in radians or degrees?

What is this 0 to 1 thing exactly? How could I rotate the layer absolutely to 170 degrees, for example?
CALayer* viewLayer = myView.layer;
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.fromValue = [NSNumber numberWithFloat:0.0 * M_PI];
animation.toValue = [NSNumber numberWithFloat:1.0 * M_PI];
animation.duration = 1.0;
animation.cumulative = YES;
animation.repeatCount = 2;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[viewLayer addAnimation:animation forKey:#"transform.rotation.z"];
Not knowing an Cocoa, I would say that the toValue specifies 1.0Pi radian rotation. There are 2Pi radians in 360 degrees. Hence 1.0Pi represents 180 degrees. To get a 170 degree rotation I would set toValue as
animation.toValue = [NSNumber numberWithFloat:(170.0/180.0) * M_PI];

How can I enforce an specific direction (i.e. clockwise) of rotation in Core Animation?

I am rotating a view with this:
CGAffineTransform rotatedTransform = CGAffineTransformRotate(CGAffineTransformIdentity, rotationValue);
I have an object which I want to spin around for about 320 degrees. Now Core Animation is clever and just rotates it as much as needed, doing that by rotating it with -40 degrees. So the object rotates the other way around with a shorter amount of movement.
I want to constrain it to rotate clockwise. Would I have to do that by changing animations in little steps, or is there an more elegant way?
The following snippet rotates a view called someView by using key-framed animation. The animation consists of 3 frames spread over 1 second, with the view rotated to 0º, 180º and 360º in the first, second and last frames respectively. Code follows:
CALayer* layer = someView.layer;
CAKeyframeAnimation* animation;
animation = [CAKeyframeAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.duration = 1.0;
animation.cumulative = YES;
animation.repeatCount = 1;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
animation.values = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0 * M_PI],
[NSNumber numberWithFloat:0.5 * M_PI],
[NSNumber numberWithFloat:1.0 * M_PI], nil];
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:0.5],
[NSNumber numberWithFloat:1.0], nil];
animation.timingFunctions = [NSArray arrayWithObjects:
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear], nil];
[layer addAnimation:animation forKey:#"transform.rotation.z"];
If you're after counterclockwise animation, you should use negative values. For a slightly more basic animation, you can use CABasicAnimation:
CALayer* layer = someView.layer;
CABasicAnimation* animation;
animation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.fromValue = [NSNumber numberWithFloat:0.0 * M_PI];
animation.toValue = [NSNumber numberWithFloat:1.0 * M_PI];
animation.duration = 1.0;
animation.cumulative = YES;
animation.repeatCount = 1;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[layer addAnimation:rotationAnimation forKey:#"transform.rotation.z"];
I believe you have to give it another "key frame" if you will to give Core Animation the hint that it needs to go that direction.
Make sure and turn off easing, (at least for the end/beginning of the middle step) otherwise the animation will not look smooth.

Load an animation image while running a function in Iphone SDK

I want to load an animation image while running a function (like: loading....).
How can I do in iphone SDK?
Use CoreAmination.
self.layer.transform = CATransform3DRotate(self.layer.transform, M_PI, 0.f, 0.f, 1.f);
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"transform"];
animation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
animation.autoreverses = NO;
animation.duration = 1.00;
//animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.repeatCount = HUGE_VALF;
[self.layer addAnimation:animation forKey:#"spinner"];

Moving Image 360 Degree

How can we Move an Image 360 Degree from the starting point to the ending point?
Moving Image 360 Degree?
You can rotate a view, by some number of radians, regardless of whether it is less than a full rotation or many multiples of a full rotation, without having to split the rotation into pieces. As an example, the following code will spin a view, once per second, for a specified number of seconds. You can easily modify it to spin a view by a certain number of rotations, or by some number of radians.
- (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"];
}
A 360 degree rotation in any axis leaves the view unchanged. So don't touch the image, and you're good to go!
You could use an animation function (CAValueFunction) for this too:
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:#"transform"];
rotationAnimation.duration = duration;
rotationAnimation.fromValue = [NSNumber numberWithFloat:0.0];
rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2.0];
rotationAnimation.valueFunction = [CAValueFunction functionWithName:kCAValueFunctionRotateZ];
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[myView.layer addAnimation:rotationAnimation forKey:nil];