如何使用重复动画同步另一个对象?

时间:2014-07-25 03:33:07

标签: ios objective-c animation

我有一个动画,涉及一个物体在两个墙之间来回连续弹跳,两个位置之间的时间间隔为2秒,由CGPoints' positionStart'和' positionEnd'。执行此操作的代码是一个非常简单和基本的动画:

CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:@"position"];
theAnimation.duration=1.0;
theAnimation.beginTime=CACurrentMediaTime()+1;
theAnimation.repeatCount=HUGE_VALF;
theAnimation.autoreverses=YES;
theAnimation.fromValue=[NSValue valueWithCGPoint:positionStart];
theAnimation.toValue=[NSValue valueWithCGPoint:positionEnd];
[self.pulseLayer addAnimation:theAnimation forKey:@"animatePosition"];

现在问题是:我想让这部分代码向每个" tick"发送一条消息给另​​一个对象。这个时钟;也就是说,每当pulseLayer呈现的位置进入' positionStart'我希望这部分代码将目标操作消息发送到另一个对象(让我们称之为时钟#2),我希望与“脉冲层”的周期性弹跳保持同步。

有没有简单的方法呢?我能提出的最好的替代想法是(1)在动画开始的同时启动NSTimer以发送" tick"定时脉冲到时钟#2,但我担心虽然NSTimer对象和' pulseLayer'弹跳可以同步开始,小的定时错误可能会随着时间的推移而累积,以便它们在很长一段时间后不再显示为同步。肯定没有什么可以迫使他们保持同步。另一个想法(2)是废除pulseLayer的这种无休止的弹跳(即,将theAnimation.repeatCount更改为等于0)并让另一个对象发送定时脉冲以每隔2秒向该对象和该对象发起一次反弹动画。 "时钟#2"我希望保持同步的对象。

有关实现我想要做的最佳方式的想法吗?

1 个答案:

答案 0 :(得分:1)

autoreverse不发送通知

(直到所有动画完成,这在上面的示例中从未出现过)

使用2种不同的动画。设置简单:

<强>设定:

// To
self.toAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
self.toAnimation.duration=1.0;
self.toAnimation.fromValue=[NSValue valueWithCGPoint:positionStart];
self.toAnimation.toValue=[NSValue valueWithCGPoint:positionEnd];
self.toAnimation.delegate:self;

// And fro
self.froAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
self.froAnimation.duration=1.0;
self.froAnimation.fromValue=[NSValue valueWithCGPoint:positionEnd];
self.froAnimation.toValue=[NSValue valueWithCGPoint:positionStart];
self.froAnimation.delegate:self;

开始:

// Start the chain of animations by adding the "next" (the first) animation
[self toAndFro:self.froAnimation];

<强>代表:

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished {
    [self toAndFro:(CABasicAnimation*)animation];
}

<强>核心:

- (void)toAndFro:(CABasicAnimation *)stoppedAnimation {
    BOOL wasFro = self.froAnimation == stoppedAnimation;
    CABasicAnimation * theAnimation = ((wasFro)
                                       ? self.toAnimation
                                       : self.froAnimation);

    [self.pulseLayer addAnimation:theAnimation forKey:@"animatePosition"];

    // Tick here! You are now in perfect sync
}