how to animate the circle image using CAKeyFrameAnimation - ios

I'm new in ios development.
I'm implementing an Animation project and I have a circle.png image.
How can I rotate the image using CAKeyFrameAnimation on that image?

Code:-
-(void)spinAnimation
{
CABasicAnimation *rotation;
rotation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
rotation.fromValue = [NSNumber numberWithFloat:0];
rotation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
rotation.duration = 1.1; // Speed
rotation.repeatCount = HUGE_VALF; // Repeat forever. Can be a finite number.
[yourimageview.layer addAnimation:rotation forKey:#"Spin"];
}
Hope it helps.

Related

Glitches when queuing CAAnimations

I have a CAShapeLayer where I animate a circle. The animation is to first "undraw" the circle clockwise and then redraw the circle clockwise. Sort of a "rotating circle". Another way to put it: Move path stroke end point to start, then move the start point to the end.
The animation itself works, but it produces glitches now and then. It manifests in a short glimpse of the entire circle when it is supposed to be "undrawn".
Why does this occur and how can you fix it?
Thanks,
// Shape creation
layer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.width - 2 * OUTER_BORDER_WIDTH, self.width - 2* OUTER_BORDER_WIDTH)].CGPath;
// Animation queuing
-(void) applyNextAnimation
{
CABasicAnimation* animation;
if (self.animatingOpening)
{
animation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = NO;
}
else
{
animation = [CABasicAnimation animationWithKeyPath:#"strokeStart"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = YES;
}
animation.duration = 1.0f;
animation.autoreverses = NO;
animation.delegate = self;
animation.removedOnCompletion = YES;
[self.outerCircleLayer addAnimation:animation forKey:#"stroke"];
}
// Animation stop callback
-(void) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
if (self.isAnimating)
{
[self applyNextAnimation];
}
}
It blinks becuase you are not setting the corresponding property on the layer. So when the animation completes, the layer's model is still in the pre-animated state and that is what you see momentarily between the two animations.
This will get you towards what you want...
if (self.animatingOpening)
{
self.outerCircleLayer.strokeStart = 0.0;
animation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = NO;
}
else
{
self.outerCircleLayer.strokeStart = 1.0;
animation = [CABasicAnimation animationWithKeyPath:#"strokeStart"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
self.animatingOpening = YES;
}
animation.duration = 1.0f;
animation.autoreverses = NO;
that almost works, but you will notice a more subtle glitch as you transition from the undrawn state to start animating the drawing state. The beginning of the circle has a small reverse animation as it starts. This is an implicit animation triggered by setting strokeStart from 1.0 to 0.0: which you need to get rid of so that all of the animations effects are under your control. You can achieve that most simply by setting disableActions to YES on CATransaction:
[CATransaction setDisableActions:YES];
( add it just above if (self.animatingOpening))

CABasicAnimation of object around itself (360 degrees)

Here's my Animation code:
CABasicAnimation *fullRotation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
fullRotation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
fullRotation.duration = 4;
fullRotation.repeatCount= 1000;
[[stick layer] addAnimation:fullRotation forKey:#"60"];
fullRotation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
I'm trying to rotate "stick" around itself , but it seems that it's rotating around another point , which is by default the origin. What can I do to make it accomplish a full 360 degrees rotation around itself? Thanks in advance.
If you want to change the anchor point of stick use:
stick.layer.anchorPoint = CGPointMake(1.0,1.0);
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instp/CALayer/anchorPoint
The rotation code I use:
CABasicAnimation *rotateAnim = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
rotateAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
rotateAnim.fromValue = [NSNumber numberWithFloat:0];
rotateAnim.toValue = [NSNumber numberWithFloat:(360 * M_PI / 180.0f)];
rotateAnim.repeatCount = HUGE_VALF;
rotateAnim.duration = 2.5;
rotateAnim.removedOnCompletion = NO;
[view.layer addAnimation:rotateAnim forKey:#"rotationAnimation"];

CALayer explicit animation

Guys I'm trying to perform a CABasicAnimation (just for the test purposes) following the Apple's guide
There's a piece of code:
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
fadeAnim.fromValue = [NSNumber numberWithFloat:1.0];
fadeAnim.toValue = [NSNumber numberWithFloat:0.0];
fadeAnim.duration = 5.0;
[theLayer addAnimation:fadeAnim forKey:#"opacity"];
// Change the actual data value in the layer to the final value.
theLayer.opacity = 0.0;
Which tells that I should actually change a property at the end. But it seems not working fine(it changes opacity immediately) - the duration is not 5 (I changed it to 5 for better visibility) so the animation is not CABasicAnimation but implicit.
It only works when I set theLayer.opacity = 0.0; BEFORE I add the animation to layer. Am I doing something wrong or it is a bug in docs?
P.S running the latest XCode, iOS 7.1 simulator.
Update the model layer before adding the animation.
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:#"opacity"];
fadeAnim.fromValue = [NSNumber numberWithFloat:1.0];
fadeAnim.toValue = [NSNumber numberWithFloat:0.0];
fadeAnim.duration = 5.0;
// Change the actual data value in the layer to the final value.
theLayer.opacity = 0.0;
[theLayer addAnimation:fadeAnim forKey:#"opacity"];

CABasicAnimation how to get current angle of rotation

I have some problem with CABasicAnimation. It`s similar to that post: CABasicAnimation rotate returns to original position
So, i have uiimageview that rotate in touchMove. In touchEnd invoke method that do "animation of inertia" :
-(void)animationRotation: (float)beginValue
{
CABasicAnimation *anim;
anim = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
anim.duration = 0.5;
anim.repeatCount = 1;
anim.fillMode = kCAFillModeForwards;
anim.fromValue = [NSNumber numberWithFloat:beginValue];
[anim setDelegate:self];
anim.toValue = [NSNumber numberWithFloat:(360*M_PI/180 + beginValue)];
[appleView.layer addAnimation:anim forKey:#"transform"];
CGAffineTransform rot = CGAffineTransformMakeRotation(360*M_PI/180 + beginValue);
appleView.transform = rot;
}
This animation works fine, but if I invoke touchBegan before animationRotation ended, angle of rotation is beginValue. I need cath current angle of rotation. As an experiment, i declare method
-(vod) animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
NSLog(#"Animation finished!");
}
and it's seems working. but I don't know how get that value of angle or CGAffineTransform for my UIImageView in animationDidStop.
It's even possible to do? Thanks.
you should use presentationLayer method to get layer properties during animation in flight.
so your code should be like this,
#define RADIANS_TO_DEGREES(__ANGLE__) ((__ANGLE__) / (float)M_PI * 180.0f)
-(void)animationRotation: (float)beginValue
{
CABasicAnimation *anim;
anim = [CABasicAnimation animationWithKeyPath:#"transform.rotation.z"];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
anim.duration = 0.5;
anim.repeatCount = 1;
anim.fillMode = kCAFillModeForwards;
anim.fromValue = [NSNumber numberWithFloat:beginValue];
[anim setDelegate:self];
//get current layer angle during animation in flight
CALayer *currentLayer = (CALayer *)[appleView.layer presentationLayer];
float currentAngle = [(NSNumber *)[currentLayer valueForKeyPath:#"transform.rotation.z"] floatValue];
currentAngle = roundf(RADIANS_TO_DEGREES(currentAngle));
NSLog(#"current angle: %f",currentAngle);
anim.toValue = [NSNumber numberWithFloat:(360*M_PI/180 + beginValue)];
[appleView.layer addAnimation:anim forKey:#"transform"];
CGAffineTransform rot = CGAffineTransformMakeRotation(360*M_PI/180 + beginValue);
appleView.transform = rot;
}

"Red alert" animation effect with Quartz 2D or CALayer animation?

I am new to animations and I just can not find data on how to create an alert light (simple red alert light that flickers).
I know how to animate CALayer and the basics of Quartz 2D, I am just looking for a tutorial or direction on how to achieve back light effect?
Thanks
Shani
Very hacky code (works but try not using it in production):
self.uiView1.backgroundColor = [UIColor redColor];
CABasicAnimation* selectionAnimation1 = [CABasicAnimation
animationWithKeyPath:#"opacity"];
selectionAnimation1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
selectionAnimation1.fromValue = [NSNumber numberWithFloat:0.0];
selectionAnimation1.toValue = [NSNumber numberWithFloat:1.0];
selectionAnimation1.duration = 0.10;
selectionAnimation1.repeatCount = 20;
[self.uiView1.layer addAnimation:selectionAnimation1
forKey:#"opacity"];
self.uiView2.backgroundColor = [UIColor blackColor];
CABasicAnimation* selectionAnimation2 = [CABasicAnimation
animationWithKeyPath:#"opacity"];
selectionAnimation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
selectionAnimation2.fromValue = [NSNumber numberWithFloat:1.0];
selectionAnimation2.toValue = [NSNumber numberWithFloat:0.0];
selectionAnimation2.duration = 0.10;
selectionAnimation2.repeatCount = 20;
[self.uiView2.layer addAnimation:selectionAnimation2
forKey:#"opacity"];
uiView1 & uiView2 completely overlap each other. You can replace the two uiView's with two UIImageView's, with one having an image of light turned on (red) and one with light turned off (black/gray). In which case background color change will be redundant.

Resources