Button Jiggle算法中的错误

时间:2012-07-16 06:45:03

标签: objective-c xcode

我已经实现了一个按钮摇晃动画。按下按钮摆动,但问题是动画没有停止并在[self.layer removeAllAnimations]中收到错误; 下面是代码;

 -(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 
}

2 个答案:

答案 0 :(得分:4)

您要在self.btnOption1上设置动画,因此您需要将其从self.btnOption1中删除:

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

但实际上如果你只是在动画块之外再次设置按钮的transform属性,它将删除动画:

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

(这在我的测试项目中有效。)

更新

我注意到您正在延迟启动动画,并在致电stopJiggling后立即致电animateWithDuration:... 。我不知道您为什么要使用延迟或为什么要立即致电stopJiggling

我创建了一个与您的代码匹配的测试用例:

@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

我将btnOption1 ivar连接到一个按钮,并将按钮连接到startJiggling方法。使用显示的代码,单击按钮不会执行任何操作,因为动画在添加后会立即删除。如果我注释掉removeAllAnimations消息,单击按钮会使按钮开始摇晃并且它会永远摇晃。我在iPhone 4.3模拟器,iPhone 5.0模拟器,iPhone 5.1模拟器和运行iOS 5.1的iPhone 4S上进行了测试。

所以,我无法重现你的问题。发送removeAllAnimations会删除测试中的动画。

我怀疑你只是希望动画重复两次然后停止(因为你有一个名为count的参数而你正在传递2)。如果这就是你想要做的,你可以这样做:

- (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;
    }];
}

使用+[UIView setAnimationRepeatCount:]在动画块内设置重复计数,然后在完成块中恢复按钮的变换。

答案 1 :(得分:0)

请记住导入QuartzCore / QuartzCore.h与图层对话。