动画CAEmitterLayer的emitterPosition

时间:2012-11-30 21:21:48

标签: ios cabasicanimation caemitterlayer

我正试图像这样CAEmitterLayer的{​​{1}}动画:

emitterPosition

请注意,CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"emitterPosition.x"] ; animation.toValue = (id) toValue ; animation.removedOnCompletion = NO ; animation.duration = self.translationDuration ; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut] ; animation.completion = ^(BOOL finished) { [self animateToOtherSide] ; } ; [_emitterLayer addAnimation:animation forKey:@"emitterPosition"] ; CGPoint newEmitterPosition = CGPointMake(toValue.floatValue, self.bounds.size.height/2.0) ; _emitterLayer.emitterPosition = newEmitterPosition ; 是在一个只调用相应的animation.completion委托方法的类别中声明的。

问题在于它根本没有动画并且将发射器显示在其最终位置。我的印象是,一旦将动画添加到图层,您应该将其背后的实际模型更改为其最终位置,以便在动画完成时模型处于最终状态;即,防止动画“回弹”到原来的位置。

我已尝试将最后两行放在CAAnimation块中,这确实按预期动画。但是,当动画结束时,一些粒子会在发射器的原始位置间歇性地发射。如果您将系统置于负载状态(例如,在播放动画时滚动表格视图),则会更频繁地发生这种情况。

我想到的另一个解决方案是根本不移动animation.completion,而只是移动emitterPosition本身,尽管我还没有尝试过。

提前感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:6)

也许emitterPosition.x不是动画的有效关键路径。请尝试使用emitterPosition(因此您必须提供包含在NSValue中的CGPoint值)。

我只是在我自己的机器上试过这个并且它工作正常:

CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"emitterPosition"];
ba.fromValue = [NSValue valueWithCGPoint:CGPointMake(30,100)];
ba.toValue = [NSValue valueWithCGPoint:CGPointMake(200,100)];
ba.duration = 6;
ba.autoreverses = YES;
ba.repeatCount = HUGE_VALF;
[emit addAnimation:ba forKey:nil];

要考虑的其他事项:

  • 您通常可以使用nil作为addAnimation:forKey:中的键,除非您以后需要找到此动画(例如删除它或以某种方式覆盖它)。关键路径是重要的。

  • removedOnCompletion设置为NO几乎总是错误的,通常是恶棍的最后避难所(即由于不了解动画的工作方式)。

  • 如果正如您所说,在完成块内设置_emitterLayer.emitterPosition = newEmitterPosition会设置动画,那么为什么要使用CABasicAnimation?为什么不调用UIView animate...并在动画块中设置emitterPosition?如果这样可行的话,它将一石二鸟,移动位置并为其制作动画。