我需要动画3个UIViews(淡入/淡出)。 1个动画持续时间为0.6秒(淡入/淡出周期为0.6 + 0.6秒)。但我需要在0.2秒内启动动画。
所有这些都应该“无限期地”循环(直到某些触发)。
我现在所拥有的:
- (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];
}];
}];
}
}
此代码无法预测。有时视图动画的工作方式与我想要的一样(相位为0.2秒),有时它会在同一时间开始...
这样做的正确方法是什么?我还尝试从方法签名中删除afterDelay:
部分,并启动类似于此的animateView方法,效果完全相同:
[self performSelector:@selector(animateView:) withObject:thirdView afterDelay:0.6];
更新
我注意到,当重型网络设备在后台运行时(使用AFNetworking加载大图像),动画会“中断”。
我不介意动画会“冻结”一点(虽然我更喜欢没有延迟)但我真的想保持所有动画的相位相关(相同的相位差)。
为了让问题更容易理解,我添加了图表。 Y是alpha,X是时间。前3个图 - 我想要的。最底层的 - 我现在拥有的。突出显示的区域是问题的来源。您可以看到第二个视图的动画冻结0.2秒并与第三个同步。所以他们开始在同一阶段眨眼。这只是一个例子。有时他们可以动画好,有时所有3个视图在几轮动画中“同步”并在同一阶段闪烁......
答案 0 :(得分:9)
看起来你想要同样的动画,应用于所有3个视图,偏移t = 0.2。您可以轻松地使用Core Animation完成您想要的任务。
这样做,他们将始终正确计时。
我建议:
-(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" ] ;
}
修改:哎呀!忘了开始,结束价值!
答案 1 :(得分:1)
正确安排动画的方法是使用CAMediaTiming
类符合的CAKeyframeAnimation
协议。请参阅下面的答案,获取有关如何实现此目标的资源的链接。
答案 2 :(得分:0)
尝试使用而不是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];
}];
}];
}
});
}
答案 3 :(得分: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];
}];
}];
}
}
这只是对代码的一些修改。
答案 4 :(得分:-2)
试试这个,这可能适合你。
- (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
}