我正在使用UIView类方法animateWithDuration来重复我的视图动画。我怎么能有一个可以用来稍后停止这个动画的处理程序?例如,重复动画在一个方法中启动,我需要稍后从另一个方法停止它。
答案 0 :(得分:8)
假设您已创建已取消的属性,则可以执行此类操作。如注释中所述,完成块的startAnimation调用需要包含在异步调用中以避免堆栈溢出。请务必将“id”替换为您实际拥有的任何类型。
- (void)startAnimation {
[UIView animateWithDuration:1.0
delay:0.0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^(void) {
//animate
}
completion:^(BOOL finished) {
if(!self.canceled) {
__weak id weakSelf = self;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[weakSelf startAnimation];
}];
}
}
];
}
答案 1 :(得分:8)
动画的目的是重复动画图像的反弹。如果不用担心手动停止它,那么您只需要设置三个属性(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat)
和用于移动图像的动画块代码 - self.image.center = CGPointMake(self.image.center.x, self.image.center.y+25);
以下是动画的完整代码:
[UIView animateWithDuration:0.5 delay:0 options:( UIViewAnimationOptionCurveEaseIn |
UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat |
UIViewAnimationOptionAllowUserInteraction) animations:^{self.image.center =
CGPointMake(self.image.center.x, self.image.center.y+25);} completion:nil];
就是这样。但如果您需要手动控制,则需要一些额外的代码。首先,根据jaminguy,你需要有一个BOOL属性用于指示循环/停止(self.playAnimationForImage)动画和清理单独的方法,动画代码将从其他地方调用。这是方法:
-(void)animateImageBounce{
[UIView animateWithDuration:0.5 delay:0 options:(
UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionAutoreverse |
UIViewAnimationOptionAllowUserInteraction) animations:^{self.image.center =
CGPointMake(self.image.center.x, self.image.center.y+25);} completion:^(BOOL finished){if
(finished && self.playAnimationForImage){
self.image.center = CGPointMake(self.image.center.x, self.image.center.y-25);
[self animateImageBounce];
}}];
这是从某个方法开始的动画调用
-(void)someMethod{
...
self.playAnimationForFingers = YES;
[self animateImageBounce];
}
我想要注意的是,在手动控制中,您需要在执行下一次递归调用之前重置图像的center.y。
答案 2 :(得分:3)
实际上,递归调用的解决方案对我来说没有用。动画开始表现得很奇怪:每2到3个动画重复周期,我得到动画片断。在项目的第一个弹跳部分(向下移动项目)之后,第二部分(向上移动)几乎立即执行。我认为它与递归调用有关。
因此,我拒绝使用它。解决方案是使用自动反转和重复选项启动动画,并在完整的块中检查标志(self.playAnimationForFingers
)是否指示停止动画。
-(void)animateFingersForLevelCompleteScreen{
//fix: reset the place of bouncing fingers (starting place).
//Otherwise the fingers will slowly move to the bottom at every level.
//This resetting is not working when placed inside UIView
//animate complete event block
self.image.center = CGPointMake(10 + self.image.frame.size.width/2,
95 + self.image.frame.size.height/2);
[UIView animateWithDuration:0.5 delay:0
options:(UIViewAnimationOptionCurveEaseIn |
UIViewAnimationOptionAutoreverse |
UIViewAnimationOptionRepeat |
UIViewAnimationOptionAllowUserInteraction)
animations:^{
self.image.center = CGPointMake(self.image.center.x,
self.image.center.y+25);
}
completion:^(BOOL finished){
/*finished not approapriate: finished will not be TRUE if animation
was interrupted. It is very likely to happen because animation repeats && */
if (!self.playAnimationForFingers){
[UIView setAnimationRepeatAutoreverses:NO];
}
}];
}
答案 3 :(得分:0)
U可以改为使用CABasicAnimation。
CABasicAnimation *appDeleteShakeAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
appDeleteShakeAnimation.autoreverses = YES;
appDeleteShakeAnimation.repeatDuration = HUGE_VALF;
appDeleteShakeAnimation.duration = 0.2;
appDeleteShakeAnimation.fromValue = [NSNumber numberWithFloat:-degreeToRadian(5)];
appDeleteShakeAnimation.toValue=[NSNumber numberWithFloat:degreeToRadian(5)];
[self.layer addAnimation:appDeleteShakeAnimation forKey:@"appDeleteShakeAnimation"];
然后,当你想要停止它时,你可以打电话
[self.layer removeAnimationForKey:@"appDeleteShakeAnimation"];