複数の UIView アニメーション ブロックを再生すると問題が発生します。
私が持っているのはボタンがたくさんあるゲームです。ボタンを押すと、合計ポイント量に「追加」される画面の上部にアニメーション化する UILabel が生成されます。これは、3 つのネストされたブロックを使用して行われます。これはうまく機能し、アニメーションを使用してできるだけ多くのポイント ラベルを生成できます。
//setup the label
UILabel *pointIndicator = [[UILabel alloc]initWithFrame:CGRectMake(button.button.frame.origin.x, button.button.frame.origin.y, 60, 30)];
pointIndicator.backgroundColor = [UIColor clearColor];
pointIndicator.font = [UIFont boldSystemFontOfSize:25];
pointIndicator.alpha = 0;
pointIndicator.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
pointIndicator.layer.shadowOpacity = 0.6;
pointIndicator.layer.shadowRadius = 1;
[pointIndicators addObject:pointIndicator];
[self.view addSubview:pointIndicator];
CGPoint scoreLabelPosition = [self.view convertPoint:self.totalScoreLabel.frame.origin fromView:self.totalScoreLabel.superview];
CGSize scoreLabelSize = [self.totalScoreLabel.text sizeWithFont:self.totalScoreLabel.font];
[UILabel animateWithDuration:0.3 delay:0 options:UIViewAnimationCurveEaseIn animations:^{
//Make label appear and move it above button
CGRect frame = pointIndicator.frame;
frame.origin.y -= 30;
pointIndicator.frame = frame;
pointIndicator.alpha = 1;
}completion:^(BOOL finished){
[UILabel animateWithDuration:0.4 delay:0 options:UIViewAnimationCurveEaseInOut animations:^{
//Move the label next to the score label
NSInteger YPosition = 0;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
YPosition = 15;
}else{
YPosition = 2;
}
CGRect frame = pointIndicator.frame;
frame.origin.x = scoreLabelPosition.x + self.totalScoreLabel.frame.size.width/2 + scoreLabelSize.width/2 + 5;
frame.origin.y = scoreLabelPosition.y - self.totalScoreLabel.frame.size.height/2 + YPosition;
pointIndicator.frame = frame;
}completion:^(BOOL finished){
[UILabel animateWithDuration:0.5 animations:^{
pointIndicator.alpha = 0;
}completion:^(BOOL finished){
//Animate point label to increase a bit in size
CABasicAnimation *pointAnim = [CABasicAnimation animationWithKeyPath:@"transform"];
pointAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pointAnim.duration = 0.1;
pointAnim.repeatCount = 1;
pointAnim.autoreverses = YES;
pointAnim.removedOnCompletion = YES;
pointAnim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.5, 1.5, 1.0)];
[self.totalScoreLabel.layer addAnimation:pointAnim forKey:nil];
[pointIndicator removeFromSuperview];
[pointIndicators removeObject:pointIndicator];
}];
}];
}];
ただし、ゲームが終了すると、すべてのボタンが画面の外にアニメーション表示され、画像ビューのサイズが中央から大きくなり、それぞれが 1 つのアニメーション ブロックを使用します。
問題は、UILabel がゲームの終了と同時に画面全体でアニメーション化されている場合、ボタンのアニメーションと成長する画像のアニメーションがキャンセルされることです。UILabels が生成されない場合、すべてが正常に再生されます。他のアニメーションを再生する前に、すべてのポイント ラベルをキャンセルして削除しようとしましたが、うまくいきませんでした。以前のアニメーションがすべて事前に正常に完了している場合にのみ機能するようです。これは私がそれらを削除する方法です:
for(UIView *pointView in pointIndicators){
[pointView.layer removeAllAnimations];
[pointView removeFromSuperview];
}
[pointIndicators removeAllObjects];
[self.totalScoreLabel.layer removeAllAnimations];
アニメーション化されるすべてのビューは、同じ UIView のサブビューです。ポイント ラベルをボタンのサブビューにすると、すべてのアニメーションを同時に再生できることに気付きました。
この動作を理解できないようですが、アニメーション間に何らかの競合がありますか?