2010-05-28 7 views
3

Je cherche à utiliser Core Animation pour simuler une animation d'horloge dans une application Mac. Actuellement, j'ai trois CALayer représentant la moitié supérieure et inférieure du chiffre, et un troisième utilisé pour représenter l'animation flip (une solution trouvée dans l'article suivant: Creating an iPad flip-clock with Core AnimationAnimation 'flip' de Core Animation

L'animation de la couche de retournement est divisée en deux étapes : retournement du haut au milieu du chiffre, puis du milieu au fond pour ce faire, j'utilise une fonction de délégué qui est appelée chaque fois qu'une animation se termine.

- (void)animationDidStop:(CAAnimation *)oldAnimation finished:(BOOL)flag 
{ 
    int digitIndex = [[oldAnimation valueForKey:@"digit"] intValue];  
    int currentValue = [[oldAnimation valueForKey:@"value"] intValue]; 

    NSMutableArray *digit = [digits objectAtIndex:digitIndex]; 
    CALayer *flipLayer = [digit objectAtIndex:tickerFlip]; 
    CALayer *bottomLayer = [digit objectAtIndex:tickerBottom]; 

    if([[oldAnimation valueForKey:@"state"] isEqual:@"top"] && flag) { 
     NSLog(@"Top animation finished"); 

     [CATransaction begin]; 
     [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 
     flipLayer.contents = [bottomImages objectAtIndex:currentValue]; 
     flipLayer.anchorPoint = CGPointMake(0.0, 1.0); 
     flipLayer.hidden = NO; 
     [CATransaction commit]; 

     CABasicAnimation *anim = [self generateAnimationForState:@"bottom"]; 
     [anim setValue:[NSString stringWithFormat:@"%d", digitIndex] forKey:@"digit"]; 
     [anim setValue:[NSString stringWithFormat:@"%d", currentValue] forKey:@"value"]; 
     [flipLayer addAnimation:anim forKey:nil]; 
    } else if([[oldAnimation valueForKey:@"state"] isEqual:@"bottom"] && flag) { 
     NSLog(@"Bottom animation finished"); 

     // Hide our flip layer 
     [CATransaction begin]; 
     [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 
     bottomLayer.contents = [bottomImages objectAtIndex:currentValue]; 
     flipLayer.hidden = YES; 
     flipLayer.anchorPoint = CGPointMake(0.0, 0.0); 
     [CATransaction commit]; 
    } 
} 

cette fonction de délégué utilise d'une fonction auxiliaire qui génère la transformée pour la couche retournée en fonction de son état:

- (CABasicAnimation *)generateAnimationForState:(NSString *)state 
{ 
    CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"]; 
    anim.duration = 0.15; 
    anim.repeatCount = 1; 

    // Check which animation we're doing 
    if([state isEqualToString:@"top"]) 
    { 
     anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0.0f, 1, 0, 0)]; 
     anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(M_PI/2, 1, 0, 0)]; 
    } 
    else 
    { 
     anim.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(-M_PI/2, 1, 0, 0)]; 
     anim.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeRotation(0.0f, 1, 0, 0)]; 
    } 

    anim.delegate = self; 
    anim.removedOnCompletion = NO; 

    // Set our animations state 
    [anim setValue:state forKey:@"state"]; 

    return anim; 
} 

Cette solution fonctionne mais provoque un léger scintillement lorsqu'une animation est en cours. Je crois que cela est dû à la transformation de mon calque de flip entre les animations 'top' et 'bottom'. Il est important de noter qu'après la fin de la première étape de l'animation, je place le point d'ancrage des couches de retournement en haut de l'image, en s'assurant que le retournement pivote correctement.

Actuellement, je ne sais pas si mon animation a été configurée de manière optimale. Je suis nouveau pour les transformations et Core Animation en général. Est-ce que quelqu'un peut-il me montrer la bonne direction?

+0

voir cette question http://stackoverflow.com/questions/2845281/how-do-i-perform-a-flip-and-grow-animation-like-in-iphoto-09/2904844#2904844 il est utiliser ce code Lemur Flip comme guide. Il fait ce que tu veux plutôt bien. C'est le premier résultat sur google – hooleyhoop

Répondre

1

Après

anim.removedOnCompletion = NO; 

essayez d'insérer ce code:

anim.fillMode = kCAFillModeForwards; 

Et laissez-moi savoir. Essentiellement, l'extrait de code est censé empêcher la réinitialisation qui provoque le scintillement.

Questions connexes