2013-03-27 13 views
6

Ich habe zwei Dreh Animationen in meinem CAAnimationGroup, eine, die von Null und einer anderen beginnt, die von diesem Zustand wiederholt und autoreverses:Was ist der maximale Wert für die Dauer (CFTimeInterval) für eine CAAnimationGroup?

- (void)addWobbleAnimationToView:(UIView *)view amount:(float)amount speed:(float)speed 
{ 
    NSMutableArray *anims = [NSMutableArray array]; 

    // initial wobble 
    CABasicAnimation *startWobble = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    startWobble.toValue = [NSNumber numberWithFloat:-amount]; 
    startWobble.duration = speed/2.0; 
    startWobble.beginTime = 0; 
    startWobble.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    [anims addObject:startWobble]; 

    // rest of wobble 
    CABasicAnimation *wobbleAnim = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    wobbleAnim.fromValue = [NSNumber numberWithFloat:-amount]; 
    wobbleAnim.toValue = [NSNumber numberWithFloat:amount]; 
    wobbleAnim.duration = speed; 
    wobbleAnim.beginTime = speed/2.0; 
    wobbleAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    wobbleAnim.autoreverses = YES; 
    wobbleAnim.repeatCount = INFINITY; 
    [anims addObject:wobbleAnim]; 

    CAAnimationGroup *wobbleGroup = [CAAnimationGroup animation]; 
    wobbleGroup.duration = DBL_MAX; // this stops it from working 
    wobbleGroup.animations = anims; 

    [view.layer addAnimation:wobbleGroup forKey:@"wobble"]; 
} 

Da CFTimeInterval als Doppel definiert ist, versuche ich, die Dauer der Animationsgruppe einstellen zu DBL_MAX, aber das stoppt die Animationsgruppe zu laufen. Wenn ich es jedoch auf eine große Zahl wie 10000 setze, läuft es gut. Was ist die größte Zahl, die ich für eine Dauer von einem CAAnimationGroup verwenden kann, es bis ins Unendliche wie möglich für so nahe läuft zu gewährleisten?

UPDATE: Es scheint, dass, wenn ich einen sehr großen Wert wie DBL_MAX/4.0 eingeben, dann friert es für eine Sekunde ein, dann beginnt die Animation. Wenn ich den Wert DBL_MAX/20.0 einstelle, ist das Einfrieren am Anfang viel kleiner. Es scheint, dass ein so großer Wert für die Dauer dazu führt, dass es einfriert. Gibt es einen besseren Weg, dies zu tun, als einen sehr großen Wert für die Dauer zu verwenden?

+0

Sie versuchen, diese Gruppe von Animationen für immer zu wiederholen? –

+0

ja, aber ich möchte nur den zweiten Teil der Gruppe für immer wiederholen. – jowie

+0

Sind Sie sicher, dass Sie die Dauer überhaupt einstellen müssen? Was passiert, wenn du es nicht siehst? –

Antwort

1

Ich bin gerade mit genau dem gleichen Problem konfrontiert ... Ich hoffe, jemand beweist mich falsch, aber die einzige vernünftige Art und Weise, um diese Situation zu behandeln ist durch Verschieben der ersten Animation zu einem CATransaction, und verketten das mit der Autoreverse-Animation mit:

[CATransaction setCompletionBlock:block]; 

Es ist nicht ideal, aber macht die Arbeit erledigt.

In Bezug auf Ihre Frage zu den Animationen, wenn sie von Hintergrund des Rückweg pausiert wird, dass eine klassische Begrenzung des Coreanimation Rahmen ist, viele Lösungen wurden vorgeschlagen. So wie ich es lösen ist, indem einfach die Animationen an einem beliebigen Punkt der Animation Reseting, durch die timeOffset Eigenschaft Randomisierung. Der Benutzer kann nicht genau sagen, wie der Animationsstatus sein soll, da die App im Hintergrund war. Hier ist ein Code, der (suchen Sie nach dem //RANDOMIZE!! Kommentar) helfen könnte:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(startAnimating) 
              name:UIApplicationWillEnterForegroundNotification 
              object:[UIApplication sharedApplication]]; 

... 

for (CALayer* layer in _layers) 
{ 
    // RANDOMIZE!!! 
    int index = arc4random()%[levels count]; 
    int level = ...; 
    CGFloat xOffset = ...; 

    layer.position = CGPointMake(xOffset, self.bounds.size.height/5.0f + yOffset * level); 

    CGFloat speed = (1.5f + (arc4random() % 40)/10.f); 
    CGFloat duration = (int)((self.bounds.size.width - xOffset)/speed); 

    NSString* keyPath = @"position.x"; 
    CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:keyPath]; 

    anim.fromValue  = @(xOffset); 
    anim.toValue  = @(self.bounds.size.width); 
    anim.duration  = duration; 
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    // RANDOMIZE!! 
    anim.timeOffset  = arc4random() % (int) duration; 
    anim.repeatCount = INFINITY; 

    [layer removeAnimationForKey:keyPath]; 
    [layer addAnimation:anim forKey:keyPath]; 
    [_animatingLayers addObject:layer]; 
} 
0

Es ist viel einfacher, eine einzige Keyframe-Animation zu verwenden, anstatt eine Gruppe von zwei separaten Animationen.

- (void)addWobbleAnimationToView:(UIView *)view amount:(CGFloat)amount speed:(NSTimeInterval)speed { 
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    animation.duration = 2 * speed; 
    animation.values = @[ @0.0f, @(-amount), @0.0f, @(amount), @0.0f ]; 
    animation.keyTimes = @[ @0.0, @0.25, @0.5, @0.75, @1.0 ]; 
    CAMediaTimingFunction *easeOut =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; 
    CAMediaTimingFunction *easeIn =[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
    animation.timingFunctions = @[ easeOut, easeIn, easeOut, easeIn ]; 
    animation.repeatCount = HUGE_VALF; 
    [view.layer addAnimation:animation forKey:animation.keyPath]; 
} 
Verwandte Themen