甘いものが好きです

iOS App開発時に感じた疑問や課題、その他の雑感などを書いていきます。

UIViewのアニメーションの二重実行を防ぐ

UIViewのアニメーションの二重実行を防ぐためには、実行開始時にフラグを立てて実行終了後にフラグを落とせばよい。UIViewクラスのクラスメソッドsetAnimationDelegate:でdelegateを設定すると、アニメーションが終了したタイミングでdelegateのanimationDidStop:finished:がコールされるので、このタイミングでフラグを落とす。

- (IBAction)sampleAnimation:(id)sender {
    if (!isAnimating) {
        isAnimating = YES; // 二重実行を防ぐためにフラグを立てる。
        [UIView beginAnimations:@"MoveDown" context:nil];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDuration:1.0f];
        // TODO: ここにアニメーションの内容を設定する。
        [UIView commitAnimations];
    }
}

// アニメーションの終了時にコールされる。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    isAnimating = NO; // ここでフラグを落とす。
}

アニメーション終了時のメッセージの送信先をUIViewクラスのクラスメソッドsetAnimationDidStopSelector:で設定すると、アニメーション終了時にコールされるメソッドを変更することもできる。ただし、setAnimationDidStopSelector:で指定するメソッドのシグネチャは次のような形式でなければならない。

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context;

また、setAnimationDidStopSelector:による設定を行った場合には、animationDidStop:finished:はコールされなくなる。

- (IBAction)sampleAnimation:(id)sender {
    if (!isAnimating) {
        isAnimating = YES; // 二重実行を防ぐためにフラグを立てる。
        [UIView beginAnimations:@"MoveDown" context:nil];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:);
        [UIView setAnimationDuration:1.0f];
        // TODO: ここにアニメーションの内容を設定する。
        [UIView commitAnimations];
    }
}

// このメソッドはアニメーション終了時にコールされなくなる。
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    isAnimating = NO;
}

// このメソッドがアニメーション終了時にコールされる。
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    isAnimating = NO; // ここでフラグを落とす。
}