动画完成块在完成之前运行?

时间:2016-04-02 20:27:30

标签: ios objective-c animation uiview uiviewcontroller

我使用UIViewController以模式方式显示UIModalPresentationOverCurrentContext以执行动画。

[self presentViewController:messageVC animated:NO completion:^{
[messageVC displayMessageAutoReversed:YES withBlock:^(BOOL finished) {
    if (finished) {
        [messageVC dismissViewControllerAnimated:YES completion:nil];
    }
}];
}];

messageVC内,此方法称为:

-(void)displayMessageAutoReversed:(BOOL)autoReversed withBlock:(void (^)(BOOL finished))handler {
    NSTimeInterval animationDuration = 0.4;

    [UIView animateWithDuration:animationDuration delay:0 usingSpringWithDamping:1.5 initialSpringVelocity:2.5f options:UIViewAnimationOptionTransitionNone animations:^{

        self.visualEffectView.effect = [UIBlurEffect effectWithStyle:self.blurEffectStyle];
        self.messageLabel.alpha = 1.0f;
        self.imageView.alpha = 1.0f;

    }completion:^(BOOL finished) {
        if (finished)
        {
            if (autoReversed)
            {
                [self hideMessageWithBlock:^(BOOL finished) {
                    if (handler) { handler(finished); }
                }];
            } else
            {
                if (handler) { handler(finished); }
            }
        }
    }];
}

-(void)hideMessageWithBlock:(void (^)(BOOL finished))handler {
    NSTimeInterval animationDuration = 0.4;

    [UIView animateWithDuration:animationDuration delay:animationDuration + 1.5 usingSpringWithDamping:1.5 initialSpringVelocity:2.5f options:UIViewAnimationOptionTransitionNone animations:^{

        self.visualEffectView.effect = nil;
        self.messageLabel.alpha = 0.0f;
        self.imageView.alpha = 0.0f;

    }completion:^(BOOL finished) {
        if (handler) { handler(finished); }
    }];
}

但是hideMessageWithBlock内的动画块被立即调用,而不是在1.9秒延迟之后调用 - 它会在突然反弹回模糊之前将效果设置为零。 为什么会这样?它会在nil之后闪烁,然后跳回模糊状态,然后再在另一秒后逐渐消失。

修改

double delayInSeconds = 2.0;
dispatch_time_t reverseTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(reverseTime, dispatch_get_main_queue(), ^(void) {
    /* put whole animation block here? */
});

1 个答案:

答案 0 :(得分:0)

我怀疑UIView动画方法实际上是立即执行该块以确定正在更改的可动画属性,因此您的视觉效果视图会立即设置为nil,因为它不是可动画的属性。

您可以使用简单的animateWithDuration:animationDuration delay:...并使用animateWithDuration来延迟动画,而不是使用dispatch_after

double delayInSeconds = 1.9;
dispatch_time_t reverseTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(reverseTime, dispatch_get_main_queue(), ^(void) {
    [UIView animateWithDuration:animationDuration delay:0 usingSpringWithDamping:1.5 initialSpringVelocity:2.5f options:UIViewAnimationOptionTransitionNone animations:^{

        self.visualEffectView.effect = nil;
        self.messageLabel.alpha = 0.0f;
        self.imageView.alpha = 0.0f;

    }completion:^(BOOL finished) {
        if (handler) { handler(finished); }
    }];
});