简体   繁体   中英

iOS - completion block in UIView animateWithDuration gets called too early

I'm trying to do some animation when a table view cell gets selected. For some reason, the completion block is getting called way too early. Even setting the duration to 10 seconds, the completion block gets called immediately.

[UIView animateWithDuration:10.0 animations:^{
    message.frame = newFrame;
} completion:^(BOOL finished) {
    NSLog(@"DONE???");
}];

Any thoughts on why this is happening? Thanks.

From the UIView documentation :

completion

A block object to be executed when the animation sequence ends. This block has no return value and takes a single Boolean argument that indicates whether or not the animations actually finished before the completion handler was called. If the duration of the animation is 0, this block is performed at the beginning of the next run loop cycle. This parameter may be NULL.

What this means is that there isn't a guarantee that the code will be executed only when the animation is done. I'd advise you to check the "finished" parameter as a condition for execution.

Yes. It is being called too early because it's being interrupted somehow. Probably by a modal presentation transition or perhaps something else. Depending on your needs, the following may be a solution you like. We avoid the conflict by manually delaying the execution of our animation code like so:

// To get this in Xcode very easily start typing, "dispatch_aft..."

// Note the "0.2". This ensures the outstanding animation gets completed before we start ours
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [UIView animateWithDuration:1.0 delay:0 options:0 animations:^{
        // Your animation code
    } completion:^(BOOL finished) {
        // Your completion code
    }];
});

如果动画没有效果,也可以提前调用完成,例如将视图的 alpha 设置为它已有的值。

Posting this here in case it helps. In my case I was using a keyframe animation and the completion block was called immediately. Beware these concepts:

  • duration: The duration of the overall animation, measured in seconds. If you specify a negative value or 0, changes are made immediately and without animations.

  • frameStartTime: The time at which to start the specified animations. This value must be in the range 0 to 1, where 0 represents the start of the overall animation and 1 represents the end of the overall animation. For example, for an animation that is two seconds in duration, specifying a start time of 0.5 causes the animations to begin executing one second after the start of the overall animation.

  • frameDuration: The length of time over which to animate to the specified value. This value must be in the range 0 to 1 and indicates the amount of time relative to the overall animation length. If you specify a value of 0, any properties you set in the animations block update immediately at the specified start time. If you specify a nonzero value, the properties animate over that amount of time. For example, for an animation that is two seconds in duration, specifying a duration of 0.5 results in an animation duration of one second.

Setting any of these values wrong will interfere with the time the completion gets called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM