iOS - Stop a repeating UIAnimation? - ios

I have an animation that needs to be repeated until I decided to stop it.
How can I stop in animation after a button click?
[UIView animateWithDuration:0.2 delay:0 options:(UIViewAnimationCurveLinear | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat) animations:^{
CGAffineTransform transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(5));
self.transform = transform;
} completion:^(BOOL finished){
}];

You have to add one other option UIViewAnimationOptionAllowUserInteraction ...
You should try this:
[UIView animateWithDuration:2 delay:0 options:UIViewAnimationCurveLinear | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction animations:^
{
view.frame = CGRectMake(0, 100, 200, 200);
} completion:^(BOOL finished)
{
if(! finished) return;
}];
And to stop the animation use this:
[view.layer removeAllAnimations];

U can make use of CABasicAnimation instead.
CABasicAnimation *appDeleteShakeAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
appDeleteShakeAnimation.autoreverses = YES;
appDeleteShakeAnimation.repeatDuration = HUGE_VALF;
appDeleteShakeAnimation.duration = 0.2;
appDeleteShakeAnimation.fromValue = [NSNumber numberWithFloat:-degreeToRadian(5)];
appDeleteShakeAnimation.toValue=[NSNumber numberWithFloat:degreeToRadian(5)];
[self.layer addAnimation:appDeleteShakeAnimation forKey:#"appDeleteShakeAnimation"];
Then when u want to stop it you can just call
[self.layer removeAnimationForKey:#"appDeleteShakeAnimation"];

Related

UIView Animation is far from smooth

I am trying to scale a button up and down to call attention to it.
I have tried two animation methods:
method 1
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:#"transform.scale"];
animation.autoreverses = YES;
animation.repeatDuration = 2;
animation.duration = 0.4;
animation.fromValue = #(1.0f);
animation.toValue= #(1.2f);
[button.layer addAnimation:animation forKey:#"scale"];
method 2
CGAffineTransform scaleUp = CGAffineTransformMakeScale(1.2f, 1.2f);
[UIView animateWithDuration:0.5 delay:1 options:UIViewAnimationOptionAutoreverse
animations:^{
[button setTransform:scaleUp];
} completion:^(BOOL finished) {
}];
Same problem with both animations. Near the end, when the button is scaling down to its normal scale, the animation jumps directly to scale 1.0.
Something like:
1.2 ... 1.18 ... 1.15 ... boom ... 1.0
and I see the button popping from one huge scale value to 1, instead of being smooth.
You need to set the final state of the button.In your case,the scale change like
1.0->1.1->1.2->1.1->1.0 ->1.2(jump to final state)
Gif
CGAffineTransform scaleUp = CGAffineTransformMakeScale(1.5f, 1.5f);
[UIView animateWithDuration:0.5 delay:1 options:UIViewAnimationOptionAutoreverse
animations:^{
[self.button setTransform:scaleUp];
} completion:^(BOOL finished) {
self.button.transform = CGAffineTransformIdentity;
}];

iOS continuous fade-out and fade-in animation

In objective-c, I want to add fade in and fade out animation to a UIView. I want to do the fade-out and fade-in animation continuously. To illustrate it, what effect I want to have is as following:
fade out - fade in - fade out - fade in - ...
What I'm trying is as following:
-(void)fadeOutIn:(UIView *)view duration:(NSTimeInterval)duration
{
static CGFloat alpha = 1.0;
[UIView animateWithDuration:duration
delay:0.0
options: UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveEaseInOut
animations:^{
alpha = abs((int)(alpha - 1.0));
view.alpha = alpha;
}
completion:^(BOOL finished){
}];
}
I also tried following:
-(void)fadeOutIn:(UIView *)view duration:(NSTimeInterval)duration
{
[UIView animateWithDuration:duration
delay:0.0
options: UIViewAnimationOptionRepeat| UIViewAnimationOptionCurveEaseInOut
animations:^{
view.alpha = 0.0;
}
completion:^(BOOL finished){
[UIView animateWithDuration:duration
delay:0.0
options: UIViewAnimationOptionRepeat|UIViewAnimationOptionCurveEaseInOut
animations:^{
view.alpha = 1.0;
}
completion:^(BOOL finished){
}];
}];
}
But the issue is they worked all the same, i.e., the UIView will fade out properly and SUDDENLY show up(not fade in), then fade out again...
Seems the fade in animation not work at all. Does anybody know what's wrong of my code please? Any suggestion will be highly appreciated.
Try this
[UIView animateKeyframesWithDuration:1 delay:0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse|UIViewAnimationCurveEaseInOut animations:^{
self.customIV.alpha = 0;
} completion:^(BOOL finished) {
}];
Here's this, Vigor, this does work, but I had to modify the code, this is somewhat dangerous code, due to it's constant recursiion, but you'll get the point:
-(void)fadeOutIn
{
[UIView animateWithDuration:1
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
[[self contentView] emailField].alpha = 0.0;
}
completion:^(BOOL finished){
[UIView animateWithDuration:1
delay:0.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
[[self contentView] emailField].alpha = 1.0;
}
completion:^(BOOL finished){
[self fadeOutIn];
}];
}];
}
I would really rethink how this works, I used it on a button in my view and it will recurse constanly, until the view is removed from the superview. I had to hardcode the button in the code.
[UIView animateWithDuration:duration
delay:0.0
options: UIViewAnimationOptionRepeat| UIViewAnimationOptionAutoreverse|UIViewAnimationOptionCurveEaseInOut
animations:^{
view.alpha = 0.0;
}
completion:nil];
Just call this once
Try this....
YourView.alpha = 1;// set the initial value of alpha
[UIView animateWithDuration:1 delay:0
options: UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
YourView.alpha = 0; // set the max value of alpha
} completion:nil];
This solution is for Swift 3,4 and 5
UIView.animateKeyframes(withDuration: 1, delay: 0, options: [UIView.KeyframeAnimationOptions(rawValue: UIView.AnimationOptions.repeat.rawValue), UIView.KeyframeAnimationOptions(rawValue: UIView.KeyframeAnimationOptions.RawValue(UIView.AnimationCurve.easeInOut.rawValue)), UIView.KeyframeAnimationOptions(rawValue: UIView.AnimationOptions.autoreverse.rawValue)] , animations: {
self.logoCenterImageView.alpha = 0
}) { finished in
}

How to convert a CABasicAnimation to UIView animatewithDuration

I want to convert a CABasicAnimation to UIView animatewithDuration , If there is any possible to do that?
This is my tried code so far
CABasicAnimation *myAni = [CABasicAnimation animationWithKeyPath:#"transform.scale.x"];
myAni.duration = 2.0f;
myAni.fromValue = [NSNumber numberWithFloat:1.0];
myAni.toValue = [NSNumber numberWithFloat:2.0];
[self.myView addAnimation:scaleAnimation forKey:#"myKey"];
to be in [UIView animateWithDuration.... (Instead of CABasicAnimation, I want it in animationWithDuration in the animations block.)
Is this possible? If so, how?
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
//I need it here
}
completion:^(BOOL finished){
}];
Thanks in advance
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationOptionCurveEaseInOut
animations:^{
//self.myView.transform = CGAffineTransformMakeScale(2.0,1.0);
self.testview.layer.transform = CATransform3DMakeScale(2.0,1.0,1.0);
}
completion:^(BOOL finished){
}];

How to do text field shake effect?

I'm trying to imitate the effect at login in Mac OSX: when you put a wrong password the textfield begin a nice shake effect. I tried this but I'm not satisfied.
-(void)shakeText:(UITextField*)textField
{
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationOptionAutoreverse
animations:^{textField.transform =CGAffineTransformMakeTranslation(5, 0);}
completion:^(BOOL finished) {
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationOptionAutoreverse
animations:^{textField.transform = CGAffineTransformMakeTranslation(5, 0);}
completion:nil];
}];
}
Is there a function in iOS to do it properly?
Please try the following code:
// Change the 10 & -10 values as you wish
CGAffineTransform leftWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(-10.0));
CGAffineTransform rightWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(10.0));
textField.transform = leftWobble;
[UIView animateWithDuration:0.25
delay:0
options:(UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse) animations:^{
[UIView setAnimationRepeatCount:6]; // Change this value as you want
textField.transform = rightWobble;
} completion:^(BOOL finished){
textField.transform = CGAffineTransformIdentity;
}];

Animating annotationViews (loop animation), didSelectAnnotationView doesn't work

So I am trying to animate my annotationViews using the following code :
- (void)mapView:(MKMapView *)mapView
didAddAnnotationViews:(NSArray *)annotationViews
{
LLAnnotationView *aV;
for (aV in annotationViews) {
// Don't pin drop if annotation is user location
if ([aV.annotation isKindOfClass:[MKUserLocation class]]) {
continue;
}
aV.transform = CGAffineTransformMakeScale(0, 0);
aV.alpha = 0.1;
dispatch_async(dispatch_get_main_queue(), ^(void){
[self animateAnnotationView:aV withAnnotationViews:annotationViews];
});
}
}
-(void)animateAnnotationView:(LLAnnotationView*)aV withAnnotationViews:(NSArray*)annotationViews{
#define kDurationBetweenShowUpAnimations 0.4
#define kLoopAnimationDuration 1
#define kAnimationDuration 0.4
// Initial animation
[UIView animateWithDuration:kAnimationDuration delay:kDurationBetweenShowUpAnimations*[annotationViews indexOfObject:aV]options:UIViewAnimationOptionCurveLinear animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.1, 1.1);
aV.alpha = 1.0;
}completion:^(BOOL finished){
[UIView animateWithDuration:kAnimationDuration/2 animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.0, 1.0);
aV.alpha = 0.9;
}completion:^(BOOL finished){
[UIView animateWithDuration:kAnimationDuration animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.1, 1.1);
aV.alpha = 1.0;
}completion:^(BOOL finished){
// **LOOP animation**
[UIView animateWithDuration:kLoopAnimationDuration delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^(void){
aV.transform = CGAffineTransformMakeScale(1.0, 1.0);
aV.alpha = 0.9;
}completion:^(BOOL finished){
}];
}];
}];
}];
}
Everything works as it should concerning the animation.
But when I try to select an annotation View, didSelectAnnotationView is rarely called.
I suspect that this should be thread related.
Does anyone have a clue what's going on??
Thank you.
Just found the solution. Add UIViewAnimationOptionAllowUserInteraction to the options of animateWithDuration :
[UIView animateWithDuration:kLoopAnimationDuration delay:0 options:UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionAllowUserInteraction ...
!!

Resources