我正在尝试创建动画行为,其中 View 顺时针旋转 45 度,然后在用户将其中心拖动到某条线上方时添加一个红色圆圈。将相同的 View 拖回同一条线下方会将其恢复为原始方向,然后移除红色圆圈。 View 应花费 3 秒以动画曲线旋转 45 度 UIViewAnimationCurveEaseInOut
:
我有两个函数体现了这种行为,- (void)viewHasMovedAboveLine:(UIView *)view
和 - (void)viewHasMovedBelowLine:(UIView *)view
,当用户将 View 拖动到线的上方或下方时调用。这两个函数都包含带有完成处理程序的动画,即 + (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
.完成处理程序根据需要添加或删除红色圆圈。
如果用户碰巧在动画中间将 View 拖回线,我可以通过设置 options:
使动画正确旋转至 UIViewAnimationOptionBeginFromCurrentState
并通过检查 view.layer.animationKeys.count
的值在执行动画之前删除所有动画(如果当前有通过 [view.layer removeAllAnimations]
执行的动画) .
但是,即使使用 [view.layer removeAllAnimations]
,先前动画的完成处理程序似乎仍会执行. 如果动画当前正在执行,是否有办法同时停止动画及其完成处理程序?
比起必须为每个动画创建私有(private)属性,我更喜欢更优雅的东西,例如 @property (nonatomic) BOOL animation01IsCurrentlyExecuting
和 @property (nonatomic) BOOL animation02IsCurrentlyExecuting
.理想的解决方案应包含各种动画场景,其中包含动画代码和完成处理程序。
另外:有没有办法看到动画被打断时进行了多远?我自己对时间更感兴趣(例如,动画在 2.1 秒后被打断)以便我可以确保任何进一步的动画都正确计时。
最佳答案
UIView 动画 block 的“finished”参数对于这种情况非常有用。
[UIView animateWithDuration:0.5 animations:^{
//set your UIView's animatable property
} completion:^(BOOL finished) {
if(finished){
//the animation actually completed
}
else{
//the animation was interrupted and did not fully complete
}
}];
要了解动画在被中断之前进行了多长时间,NSDate 上的一些方法可以派上用场。
__block NSDate *beginDate = [NSDate new];
__block NSTimeInterval timeElapsed;
[UIView animateWithDuration:0.5 animations:^{
//your animations
beginDate = [NSDate date];
} completion:^(BOOL finished) {
if(finished){
//the animation actually completed
}
else{
//the animation was interrupted and did not fully complete
timeElapsed = [[NSDate date] timeIntervalSinceDate:beginDate];
NSLog(@"%f", timeElapsed);
}
}];
关于objective-c - 在 iOS 的 Objective-C 中创建带有完成 block 的可中断动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12807947/