3

我正在尝试创建动画行为,其中视图顺时针旋转 45 度,然后当用户将其中心拖动到某条线上方时添加一个红色圆圈。将同一视图拖回同一行下方会将其恢复为原始方向,然后删除红色圆圈。视图应该需要 3 秒才能使用动画曲线旋转 45 度UIViewAnimationCurveEaseInOut

所需行为的可视化

我有两个体现这种行为的函数,当用户将视图拖到线的上方或下方时,它们会被调用- (void)viewHasMovedAboveLine:(UIView *)view- (void)viewHasMovedBelowLine:(UIView *)view这两个函数都包含带有完成处理程序的动画,即+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion. 完成处理程序会根据需要添加或删除红色圆圈。

如果用户碰巧在动画中间将视图拖回线,我可以让动画正确旋转,方法是设置options:UIViewAnimationOptionBeginFromCurrentState检查view.layer.animationKeys.count执行动画之前的值并删除所有动画(如果有任何当前通过[view.layer removeAllAnimations].

但是,即使在使用[view.layer removeAllAnimations]. 如果动画当前正在执行,有没有办法停止动画及其完成处理程序?

我更喜欢一些更优雅的东西,而不是必须为每个动画创建私有属性,例如,@property (nonatomic) BOOL animation01IsCurrentlyExecuting@property (nonatomic) BOOL animation02IsCurrentlyExecuting. 理想的解决方案将包含各种动画场景,其中包含动画代码和完成处理程序。

ALSO:有没有办法查看动画被打断时的进度?我自己对时间更感兴趣(例如,动画在 2.1 秒后被中断),这样我就可以确保任何进一步的动画都被正确地计时。

4

1 回答 1

1

UIView 动画块的 '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);
    }
}];
于 2013-07-30T19:52:39.280 回答