4

i have impletemented a button jiggle animation.where pressing a button wobbles ,but the problem is the animation does'nt stop and getting an error in [self.layer removeAllAnimations]; below is the code;

 -(IBAction)button1Clicked:(id)sender
 {
UIButton *no1 =sender;
output= [self answerCheck:no1.titleLabel.text];
self.label.text=output;
[self enableOptions:NO];
[self loadingView];
[self startJiggling:2];

 }
- (void)startJiggling:(NSInteger)count
{

    CGAffineTransform leftWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? +1 : -1 ) ));
    CGAffineTransform rightWobble = CGAffineTransformMakeRotation(degreesToRadians( kAnimationRotateDeg * (count%2 ? -1 : +1 ) ));
    CGAffineTransform moveTransform = CGAffineTransformTranslate(rightWobble, -kAnimationTranslateX, -kAnimationTranslateY);
    CGAffineTransform conCatTransform = CGAffineTransformConcat(rightWobble, moveTransform);

    self.btnOption1.transform = leftWobble;  // starting point

    [UIView animateWithDuration:0.1
                          delay:(count * 0.08)
                        options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse
                     animations:^{ self.btnOption1.transform = conCatTransform; }
                     completion:nil];
 [self stopJiggling];
}

-(void)stopJiggling 
{
    [self.btnOption1.layer removeAllAnimations];
    self.btnOption1.transform = CGAffineTransformIdentity;   // Set it straight 
}
Amy Worrall
  • 16,250
  • 3
  • 42
  • 65
user578386
  • 1,061
  • 3
  • 14
  • 37
  • property layer not found...i want to know the use of layer – user578386 Jul 16 '12 at 06:47
  • Well then, you're obviously calling this from a class that does not have a property called `layer`. What class are you subclassing? Is this a view controller of some kind? – Alexis King Jul 16 '12 at 06:49

2 Answers2

4

You're setting the animation on self.btnOption1, so you would need to remove it from self.btnOption1:

- (void)stopJiggling {
    [self.btnOption1.layer removeAllAnimations];
    self.btnOption1.transform = CGAffineTransformIdentity;
}

but in fact if you just set the transform property of the button again, outside of an animation block, it will remove the animation:

- (void)stopJiggling {
    self.btnOption1.transform = CGAffineTransformIdentity;
}

(This worked in my test project.)

Update:

I notice that you're starting the animation with a delay, and you're calling stopJiggling immediately after you call animateWithDuration:.... I don't know why you're using a delay or why you're calling stopJiggling immediately.

I created a test case to match your code:

@implementation ViewController {
    __unsafe_unretained IBOutlet UIButton *btnOption1;
}

- (IBAction)startJiggling {
    btnOption1.transform = CGAffineTransformMakeRotation(-.1);
    [UIView animateWithDuration:.1 delay:2 * 0.08 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
        btnOption1.transform = CGAffineTransformMakeRotation(.1);
    } completion:nil];
    [self stopJiggling];
}

- (void)stopJiggling {
    [btnOption1.layer removeAllAnimations];
    btnOption1.transform = CGAffineTransformIdentity;
}

@end

I hooked up my btnOption1 ivar to a button, and connected the button to the startJiggling method. With the code as shown, clicking the button does nothing, because the animation is removed immediately after it is added. If I comment out the removeAllAnimations message, clicking the button makes the button start jiggling and it jiggles forever. I tested on the iPhone 4.3 simulator, the iPhone 5.0 simulator, the iPhone 5.1 simulator, and my iPhone 4S running iOS 5.1.

So, I could not reproduce your problem. Sending removeAllAnimations removes the animation in my test.

I suspect that you just want the animation to repeat twice and then stop (since you have an argument named count and you're passing 2). If that's what you want to do, you can do it like this:

- (IBAction)startJiggling {
    btnOption1.transform = CGAffineTransformMakeRotation(-.1);
    [UIView animateWithDuration:.1 delay:2 * 0.08 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations:^{
        [UIView setAnimationRepeatCount:2];
        btnOption1.transform = CGAffineTransformMakeRotation(.1);
    } completion:^(BOOL completed){
        btnOption1.transform = CGAffineTransformIdentity;
    }];
}

You set the repeat count inside the animation block using +[UIView setAnimationRepeatCount:], and you restore the button's transform in the completion block.

rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Quite right. I guess I wasn't thinking. This is the correct answer. – Alexis King Jul 16 '12 at 07:08
  • I changed the above answer..pls check it out..still i m not able to stop the animation..should i got to make any changes above – user578386 Jul 16 '12 at 07:19
  • @user578386 You need to actually use that in your animation's `completion` argument. Just create a block that calls `[self stopJiggling]`, or just call the methods directly. – Alexis King Jul 16 '12 at 07:26
  • yup i called that [self stopjiggling]; but it aint stopiing – user578386 Jul 16 '12 at 07:30
  • If it's not working then there's something you're not telling us. How do you set `btnOption1`? How do you set its target and action? Do you change it anywhere? – rob mayoff Jul 16 '12 at 07:31
  • btnOption is an IBOutlet button..thats the place i call [start gigling]..updated my answer – user578386 Jul 16 '12 at 08:27
0

Remember to import QuartzCore/QuartzCore.h to talk with layers.

Dan Selig
  • 234
  • 2
  • 11