在Objective-C for iOS中使用/ completion块创建可中断动画?

时间:2012-10-09 20:31:50

标签: objective-c cocoa-touch animation uiviewanimation

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

,视图应该花费3秒钟旋转45度

Visualization of desired behavior

我有两个体现这种行为的函数,- (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。理想的解决方案将涵盖包含动画代码和完成处理程序的各种动画场景。

另外:有没有办法看到动画在被中断时有多远?我自己对计时更感兴趣(例如,动画在2.1秒后被中断)所以我可以确保任何进一步的动画都适当的定时。

1 个答案:

答案 0 :(得分: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);
    }
}];