CAAnimationGroup 的最大持续时间值 (CFTimeInterval) 是多少?
Posted
技术标签:
【中文标题】CAAnimationGroup 的最大持续时间值 (CFTimeInterval) 是多少?【英文标题】:What is the maximum duration value (CFTimeInterval) for a CAAnimationGroup? 【发布时间】:2013-03-27 17:06:36 【问题描述】:我的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"];
由于 CFTimeInterval 被定义为双精度,我尝试将动画组的持续时间设置为 DBL_MAX
,但这会阻止动画组运行。但是,如果我将其设置为较大的数字,例如 10000,则运行良好。在CAAnimationGroup
的持续时间内,我可以使用的最大数字是多少,以确保它尽可能接近无穷大?
更新:似乎如果我输入一个非常大的值,例如DBL_MAX / 4.0
,那么它会冻结一秒钟,然后开始动画。如果我输入值DBL_MAX / 20.0
,那么一开始的冻结会小很多。似乎具有如此大的持续时间值导致它冻结。除了使用非常大的持续时间值之外,还有更好的方法吗?
【问题讨论】:
你是想让这组动画永远重复吗? 是的,但我只希望小组的第二部分永远重复。 您确定需要设置持续时间吗?如果不设置会怎样? 如果我不设置它,动画根本不会运行。还有,我设置的方式,如果应用进入后台再重新打开,动画就停止了,这也是个问题。 嗯,DBL_MAX
表示大约 10^300 年。 10000
表示超过 2 小时。您希望您的应用在终止前运行多长时间?
【参考方案1】:
我现在面临着完全相同的问题......我希望有人证明我错了,但我认为处理这种情况的唯一合理方法是将第一个动画移动到 CATransaction
,并将其与自动反转动画使用:
[CATransaction setCompletionBlock:block];
这并不理想,但可以完成工作。
关于您关于从后台返回时暂停动画的问题,这是 CoreAnimation 框架的经典限制,已为此提出了许多解决方案。我解决它的方法是通过随机化timeOffset
属性来简单地在动画的随机点重置动画。用户无法准确判断动画状态应该是什么,因为应用程序在后台。下面是一些可以提供帮助的代码(查找//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];
【讨论】:
【参考方案2】:使用单个关键帧动画而不是一组两个单独的动画要简单得多。
- (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];
【讨论】:
以上是关于CAAnimationGroup 的最大持续时间值 (CFTimeInterval) 是多少?的主要内容,如果未能解决你的问题,请参考以下文章
CAAnimationGroup 中的 CAAnimation 委托
CAAnimationGroup 与 CAKeyframeAnimation 和 CABasicAnimation