链UIViewanimation与时间间隔

我需要animation3 UIViews(淡入/淡出)。 1animation持续时间为0.6s(淡入/淡出周期为0.6 + 0.6s)。 但是我需要在0.2秒内启动animation。

  • 第一个animation应该在0.0秒内启动。
  • 第二个animation应该在0.2秒内启动。
  • 应该在0.4秒内启动第三个animation。

所有这些都应该“无限期地”循环(直到某个触发器)。

我现在所拥有的:

- (void)playAnimation { isAnimated = YES; [self animateView:firstView afterDelay:0.0]; [self animateView:secondView afterDelay:0.2]; [self animateView:thirdView afterDelay:0.4]; } - (void)stopAnimation { isAnimated = NO; } - (void)animateView:(UIView *)animatedView afterDelay:(float)delay { if(isAnimated) { [UIView animateWithDuration:0.6 delay:delay options:UIViewAnimationOptionTransitionNone animations:^ { animatedView.alpha = 1.0; } completion:^(BOOL finished) { [UIView animateWithDuration:0.6 animations:^ { animatedView.alpha = 0.0; } completion:^(BOOL finished) { [self animateView:animatedView afterDelay:0.0]; }]; }]; } } 

此代码工作不可预测。 有时候,查看animation就像我想要的那样工作(相位为0.2秒),有时候它会在同一时间开始…什么是正确的方法来做到这一点? 我也试图从方法签名中删除afterDelay: part,并启动animateView方法,效果完全相同:

 [self performSelector:@selector(animateView:) withObject:thirdView afterDelay:0.6]; 

UPDATE
我注意到,当networking中的重要东西在后台执行时(使用AFNetworking加载大图像),animation“打破”了。 我不介意animation是否会“冻结”(虽然我宁愿不会有任何延迟),但是我真的想保持所有animation的相位(相同的相位差)。

为了使问题更容易理解,我添加了图表。 Y是阿尔法,X是时间。 前3个图 – 我想要的。 底部 – 我目前有。 突出的领域是问题出现的地方。 您可以看到第二个视图的animation冻结了0.2秒,并与第三个视图同步。 所以他们开始在同一个阶段闪烁。 这只是一个例子。 有些时候,他们可以animation确定,有时所有3个视图“syncronize”在几轮animation和闪烁在同一阶段… 动画

看起来你想要相同的animation,适用于所有3个视图,由t = 0.2抵消。 您可以使用Core Animation以非常小的精力完成您想要的function。

这样做,他们将始终正确计时。

我build议:

 -(void)playAnimation { CABasicAnimation * anim = [ CABasicAnimation animationWithKeyPath:@"opacity" ] ; anim.autoreverses = YES ; anim.repeatCount = CGFLOAT_MAX ; anim.removedOnCompletion = NO ; anim.duration = 0.6 ; anim.fromValue = @0.0 ; anim.toValue = @1.0; // finish configuring your animation here (timing function, speed, duration, fill mode, etc) ... CFTimeInterval t = CACurrentMediaTime() ; anim.beginTime = t ; [ self.firstView.layer addAnimation:anim forKey:@"opacity-anim" ] ; // name is so you can remove this anim later anim.beginTime += 0.2 ; [ self.secondView.layer addAnimation:anim forKey:@"opacity-anim" ] ; anim.beginTime += 0.2 ; [ self.thirdView.layer addAnimation:anim forKey:@"opacity-anim" ] ; // name is so you can remove this anim later } -(void)stopAnimation { [ self.firstView.layer removeAnimationForKey:@"opacity-anim" ] ; [ self.secondView.layer removeAnimationForKey:@"opacity-anim" ] ; [ self.thirdView.layer removeAnimationForKey:@"opacity-anim" ] ; } 

编辑 :哎呀! 忘了开始,结束价值!

正确调度animation的方法是使用CAKeyframeAnimation类符合的CAMediaTiming协议。 看到我的答案下面的资源链接如何实现这一点。

改变正在进行的CAKeyframeAnimationanimation的速度

尝试而不是performSelector:下面的示例

 - (void)animateView:(UIView *)animatedView afterDelay:(float)delay { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ if(isAnimated) { [UIView animateWithDuration:0.6 delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^ { animatedView.alpha = 1.0; } completion:^(BOOL finished) { [UIView animateWithDuration:0.6 animations:^ { animatedView.alpha = 0.0; } completion:^(BOOL finished) { [self animateView:animatedView afterDelay:0.0]; }]; }]; } }); } 

希望它能像你想要的那样工作。

 - (void)animateView:(UIView *)animatedView afterDelay:(float)delay { if(isAnimated) { [UIView animateWithDuration:0.6 delay:delay options:UIViewAnimationOptionTransitionNone animations:^ { animatedView.alpha = 1.0; } completion:^(BOOL finished) { [UIView animateWithDuration:0.6 delay:delay options:UIViewAnimationOptionTransitionNone animations:^{ animatedView.alpha = 0.0; } completion:^(BOOL finished) { [self animateView:animatedView afterDelay:delay]; }]; }]; } } 

这只是你的代码的一些修改。

试试这个,这可能适合你。

 - (void)playAnimation { isAnimated = YES; [self performSelector:@selector(animateView:) withObject:firstView afterDelay:0.1]; [self performSelector:@selector(animateView:) withObject:secondView afterDelay:0.2]; [self performSelector:@selector(animateView:) withObject:thirdView afterDelay:0.4]; } - (void)animateView:(UIView *)animatedView { //Here "animatedView" will contain (firstView/secondView/thirdView) whatever you are passing //your animation }