What is the maximum duration (CFTimeInterval) for a CAAnimationGroup?

I have two rotation animations in my CAAnimationGroup , which starts from zero, and the other, repeating and autoversion from this state:

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

Since CFTimeInterval is defined as double, I'm trying to set the animation group duration to DBL_MAX , but this stops the animation group from starting. However, if I install it on a large number, for example 10000, it works fine. What is the maximum number I can use during a CAAnimationGroup to ensure that it works as close to infinity as possible?

UPDATE: It seems that if I put a very large value, for example DBL_MAX / 4.0 , then it freezes for a second and then starts the animation. If I set the value DBL_MAX / 20.0 , then the freeze at the beginning is much less. It seems that so much importance for duration causes it to freeze. Is there a better way to do this otherwise than using a very large value for duration?

+6
source share
2 answers

Now I am facing the same problem ... I hope someone will prove to me that I am wrong, but the only reasonable way I deal with is to transfer the first animation to CATransaction and associate it with auto-reverse animation using:

 [CATransaction setCompletionBlock:block]; 

He is not perfect, but he does his job.

As for your question that the animation pauses, returning from the background, this is a classic limitation of the CoreAnimation framework, many solutions have been proposed for this. The way I solve this is to simply restart the animation at a random point in the animation by randomizing the timeOffset property. The user cannot determine the exact state of the animation because the application was in the background. Here is some code that could help (look for a comment //RANDOMIZE!! ):

 [[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]; } 
+1
source

It is much easier to use a single keyframe animation instead of a group of two separate animations.

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

All Articles