Cannot stop Animation - ios

I am using the following code to make text in a label blink :
- (void)blinkAnimation:(NSString *)animationID finished:(BOOL)finished target:(UILabel *) target {
NSString *selectedSpeed = [[NSUserDefaults standardUserDefaults] stringForKey:#"EffectSpeed"];
float speedFloat = (0.50 - [selectedSpeed floatValue]);
[UIView beginAnimations:animationID context:(__bridge void *)(target)];
[UIView setAnimationDuration:speedFloat];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(blinkAnimation:finished:target:)];
if([target alpha] == 1.0f)
[target setAlpha:0.0f];
else
[target setAlpha:1.0f];
[UIView commitAnimations];
}
and I am using the following code to make the animation Stop :
- (void) stopAnimation{
[self.gameStatus.layer removeAllAnimations];
}
Although the animation works fine, I cannot stop it.
Could you please help!
Thanks in advance....

The problem is that your animationDidStopSelector is being called when you manually stop your animation, but that method is just starting another animation. So you're stopping it ok, but you're immediately firing off another animation.
Personally, I'd suggest getting rid of the animationDidStopSelector and use the autoreverse and repeat features of the animation:
[UIView beginAnimations:animationID context:nil];
[UIView setAnimationDuration:speedFloat];
[UIView setAnimationDelegate:self];
[UIView setAnimationRepeatAutoreverses:YES];
[UIView setAnimationRepeatCount:CGFLOAT_MAX];
[target setAlpha:0.0f];
[UIView commitAnimations];
That should fix it, but as holex said, you should use block animation. I quote from the documentation: "Use of this method [beginAnimations] is discouraged in iOS 4.0 and later. You should use the block-based animation methods to specify your animations instead."
So, the equivalent block animation would be:
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
self.gameStatus.alpha = 0.0;
}
completion:nil];
Whichever technique you use, your removeAllAnimations will now work as expected.
As an aside, when you stop animations, it will set alpha immediately to zero. It might be more graceful to stop the repeating animation and then animate the alpha from the current value to your desired final value. To do that, you'll want to grab the current opacity from the presentation layer and then animate alpha from that to whatever you want it to stop at (in my example 1.0, but you could use 0.0, too):
CALayer *layer = self.gameStatus.layer.presentationLayer;
CGFloat currentOpacity = layer.opacity;
[self.gameStatus.layer removeAllAnimations];
self.gameStatus.alpha = currentOpacity;
[UIView animateWithDuration:0.25
animations:^{
self.gameStatus.alpha = 1.0;
}];

Related

How to repeat shake animation indefinitely or X times using animateWithDuration?

The code below came from this SO question: UIView shake animation.
This shake animation is perfect, except it stops after one iteration. How do you repeat the animation indefinitely, or how do you cause it to repeat it X times?
There are other SO answers on repeating UIView animations that suggest using CAKeyframeAnimation or CABasicAnimation, but this question is different. The goal is to reproduce this exact animation, with the "springy" effect from usingSpringWithDamping and initialSpringVelocity.
Using Autoreverse and Repeat don't reproduce the desired effect because the the initial translation is outside the animation block.
view.transform = CGAffineTransformMakeTranslation(20, 0);
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
view.transform = CGAffineTransformIdentity;
} completion:nil];
If you need exact same code few times than put that code in method and do recursion, something like that:
- (void)animateCount:(NSInteger)count {
if (count == 0) {
return;
}
view.transform = CGAffineTransformMakeTranslation(20, 0);
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
view.transform = CGAffineTransformIdentity;
} completion:^{
count--;
[self animateCount:count];
}];
}
Use (UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat) in options to repeat it indefinitely
[UIView animateWithDuration:0.4 delay:0.0 usingSpringWithDamping:0.2 initialSpringVelocity:1.0 options:(UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionCurveEaseInOut) animations:^{
someView.frame = someFrame1;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5f animations:^{
someView.frame = someFrame2;
} completion:nil];
}];

ImageView Animation Repeatition

I am working on an application which needs animations with imageView.
At starting the position of image is at CGPoint(735,112),on clicking the animation button it has to move to the left of the screen ie to point CGPoint(20,112) and hast to repeat the animation from left to right i.e to point CGPoint(735,112),has to stop after this. i am using the following Code.
CGRect newRect=cleanStrip.frame;
[UIView beginAnimations:#"animation1" context:nil];
[UIView setAnimationDuration:3.0];
[UIView setAnimationDelegate:self];
[UIView setAnimationRepeatAutoreverses:YES];
newRect.origin.x=20;
cleanStrip.frame=newRect;
[UIView commitAnimations];
After repeating the animation the image view has to stop at it original position CGPoint(735,112).But the above code stops the image at CGPoint(20,112).
How can i stop the image at its original position after animation.
Thanks,
you can use block to start your animation
__block CGRect newRect=cleanStrip.frame;
__block int originx = newRect.origin.x;
[UIView animateWithDuration:2.0
animations:^{
newRect.origin.x=20;
cleanStrip.frame=newRect;
}
completion:^(BOOL finished){
[UIView animateWithDuration:2.0
animations:^{
newRect.origin.x=originx ;
cleanStrip.frame=newRect;
}];
}];

How to animate overlay drawing in MKMapView

I'm drawing MKCircleView overlay on MKMapView. it works fine, except that I need to animate drawing of this overlay.
I know that I need to use:
[UIView beginAnimations:nil context:NULL];
[UIView commitAnimations];
,but I don't know where to put this animation code.
Thanks.
not sure what you're looking for.. but for example:
[UIView beginAnimations:#"fade" context:nil];
[UIView setAnimationDuration:0.6f];
theView.alpha = 0.0f;
theView.transform = CGAffineTransformMakeScale(0.01,0.01);
theView.alpha = 1.0f;
[UIView commitAnimations];

removing UIView Animation acceleration

How does one remove the acceleration and deceleration animation that UIView Animations do?
If you don't understand what I mean, when an animation starts up it accelerates and then when it get to the end, it decelerated. I want the animation to be a constant speed.
Here is an example of what my code looks like (I MUST use the old animation ways).
-(void)animate:(NSString*)animationID finished:(BOOL)finished context:(void*)context {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDidStopSelector:#selector(animateStop:finished:context:)];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:3];
Motion.center = (*PathPoints)[Location];
[UIView commitAnimations];
}
[UIView setAnimationCurve: UIViewAnimationCurveLinear];

Core Animation to flash score (UILabel)

I am using core animation to flash intermediate scores (using UILabel) in a game on iPhone. I need it to repeat for certain count for a particular hit.
The score needs to be flashed for a particular count and then disappear.
So it should go from alpha 0.0 -> 1.0 -> 0.0
Below is the code with which I am trying to achieve this.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:repeatCount];
[UIView setAnimationRepeatAutoreverses:YES];
playerScore.alpha = 1.0f;
[UIView commitAnimations];
The problem is that after the animation is over, the alpha returns back to 1.0
Any suggestions?
I would use the more powerful animateWithDuration:delay:options:animations:completion: method on UIView. See View programming guide or UIView class reference
More specifically it could look like that: the method takes two blocks: one for the animation itself and one block which is execute once the animation is done. It maybe look a bit strange at first sight, but that is just the block syntax.
[UIView animateWithDuration:1.0 delay:0.f options:(UIViewAnimationOptionAutoreverse| UIViewAnimationOptionRepeat)
animations:^{
playerScore.alpha=1.f;
} completion:^(BOOL finished){
playerScore.alpha=0.f;
}];
This solution is for iOS version 4 or higher. If you want to target versions before that, you have to use a delegate callback. Set the selector to be executed when the animation is done like this:
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(flashingDidStop:finished:context:)];
//with the callback method
- (void)flashingDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
//code to execute in your case
playerScore.alpha = 0.f;
}
If you need this to work in iOS < 4.0 try this:
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
playerScore.alpha = 0.0f;
}
...
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(animationDidStop:finished:context:)];
[UIView setAnimationDuration:1.0];
[UIView setAnimationRepeatCount:repeatCount];
[UIView setAnimationRepeatAutoreverses:YES];
playerScore.alpha = 1.0f;
[UIView commitAnimations];

Resources