我正在构建一个iOS应用程序,在这个应用程序中,我需要通过选择颜色来实现动画视图的backgroundColor。在我的viewDidLoad方法中,我基本上使用以下方法触发了一系列UIView动画。
-(void) beginFirstStageBackgroundAnimation
{
[UIView animateWithDuration: 3.0f
delay: 3.0f
options: UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.view.backgroundColor = [UIColor colorWithRed: 251./255 green:203./255 blue:147./255 alpha:1.0];
}
completion:^(BOOL finished){
[self secondStageBackgroundAnimation];
}
];
}
完成处理程序触发包含下一个颜色的第二个方法....
-(void) secondStageBackgroundAnimation
{
[UIView animateWithDuration: 3.0f
delay: 3.0f
options: UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.view.backgroundColor = [UIColor colorWithRed:251./255 green:224./255 blue:96./255 alpha:1.0];
}
completion:^(BOOL finished){
[self thirdStageBackgroundAnimation];
}
];
}
等等......这一直持续到第七个动画中我在完成时调用[self beginFirstStageBackgroundAnimation];
以再次开始该过程。
当我使用后退按钮离开视图时,在viewDidDisappear中或当显示器上的计时器结束时,我运行[self.view.layer removeAllAnimations];
以完全摆脱动画。然而,该应用程序运行并完全按预期工作,但似乎在离开视图并运行整体后崩溃,虽然我不知道为什么它似乎与此动画链相关。
是否有更好的解决方案,每隔3秒钟为视图的backgroundColor设置动画,延迟时间为3秒?
[self.view.layer removeAllAnimations];
实际上做了我想做的事吗?
编辑:我离开视图的代码如下:
-(void) backBtnPressed:(id)sender
{
[self stopAudio]; // stop audio that is playing.
[self.view.layer removeAllAnimations]; // remove all animations?
[self.navigationController popViewControllerAnimated: YES]; // pop view from stack
}
答案 0 :(得分:7)
我认为要走的路是在参数化上代表你想要在每个动画中发生的事情(在这种情况下只是一种颜色),然后将这些参数保存在一个数组中。该数组就像您的动画待办事项列表:
@property(strong, nonatomic) NSArray *animationTodo;
我们还需要跟踪列表中的位置。使用盒装(NS)编号,以便我们可以将“不动画”表示为零,与索引零不同:
@property(strong, nonatomic) NSNumber *animationIndex;
使用颜色初始化数组:
self.animationTodo = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], ... nil];
现在可以将动画压缩为单个方法:
- (void)animate {
if (!animationIndex) return;
NSInteger index = [animationIndex intValue];
[UIView animateWithDuration:3.0 animations:^{
self.view.backgroundColor = [animationToDo objectAtIndex:index];
} completion:^(BOOL finished) {
NSInteger nextIndex = (index==self.animationTodo.count-1)? 0 : index+1; // advance index in a ring
self.animationIndex = [NSNumber numberWithInt:nextIndex];
// schedule the next one in 3s
[self performSelector:@selector(animate) withObject:nil afterDelay:3.0];
}];
}
执行选择器让你说明延迟,并且每次开始下一个动画时都会产生不卷起叠加的正面效果。
现在停止也很简单。在视图消失之前以及您希望停止的任何其他时间执行此操作。
- (void)stopAnimating {
self.animationIndex = nil;
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
答案 1 :(得分:5)
您可以尝试使用CAAnimation
我认为管理颜色和动画会更容易
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSArray *colors = @[[UIColor greenColor],
[UIColor redColor],
[UIColor blueColor],
[UIColor yellowColor],
[UIColor orangeColor]
];
NSMutableArray *animations = [NSMutableArray new];
float colorAnimationDuration = 3.0f;
for (int i = 0; i < colors.count; i++)
{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
animation.toValue = (id)[[colors objectAtIndex:i] CGColor];
animation.duration = colorAnimationDuration;
animation.beginTime = i * colorAnimationDuration;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[animations addObject:animation];
}
CAAnimationGroup *animationsGroup = [CAAnimationGroup new];
animationsGroup.duration = colors.count * colorAnimationDuration;
animationsGroup.repeatCount = HUGE_VALF;
animationsGroup.animations = animations;
[self.view.layer addAnimation:animationsGroup forKey:@"myAnimations"];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.view.layer removeAnimationForKey:@"myAnimations"];
}
答案 2 :(得分:-1)
尝试在每个动画方法中添加一个检查,如下所示:
-(void) secondStageBackgroundAnimation
{
if (self.view.superview){
[UIView animateWithDuration: 3.0f
delay: 3.0f
options: UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.view.backgroundColor = [UIColor colorWithRed:251./255 green:224./255 blue:96./255 alpha:1.0];
}
completion:^(BOOL finished){
[self thirdStageBackgroundAnimation];
}
];
}
}
您可以将代码发布到“使用后退按钮离开视图”吗?问题可能就在那里......