Search code examples
objective-cblockuiviewanimation

Canceling an UIView Animation Block


The code below shows an animation of a label which contains a status message for the user. If an event happens the label is showing prompt and is slowly disappearing via uiview animation block.

- (void)showStatusOnLabelWithString:(NSString *)statusMessage
{   
    // [self.view.layer removeAllAnimations]; // not working
    [labelStatus.layer removeAllAnimations]; // not working, too

    [labelStatus setText:statusMessage];
    [labelStatus setHidden:NO];
    [labelStatus setAlpha:1.0];

    [UIView animateWithDuration:5.0 animations:^
     {
         [labelStatus setAlpha:0.0];

     } completion:^(BOOL finished) 
     {
         [labelStatus setHidden:YES];
         [labelStatus setAlpha:1.0];
     }];
}

If there is another event in the following 5s after the first the label should animate again, so I removed the previous animation with [self.view.layer removeAllAnimations] (thats what I thought). But the label just completely disappear and the next 5s the label is invisible again.

If I (or the user) wait(s) the 5s everything is working properly.

Why isn't this working?

Kind Regards, $h@rky


Solution

  • Change this:

    completion:^(BOOL finished) 
     {
         [labelStatus setHidden:YES];
         [labelStatus setAlpha:1.0];
     }];
    

    to this:

    completion:^(BOOL finished) 
     {
         if (finished) {
             [labelStatus setHidden:YES];
             [labelStatus setAlpha:1.0];
         }
     }];
    

    The reason is you are reaching this completion block when you remove the animations for the layer, but finished will be false because you interrupted it. Also, the order is important here. Perhaps you were expecting removeAllAnimations to call the completion block instantly, but instead it will be called after your showStatusOnLabelWithString: method finishes, so what is happening is you are calling setHidden:NO followed immediately by setHidden:YES.