Search code examples
iosobjective-cuiviewcore-animation

Stopping animateWithDuration before completion


I have this method in a UIViewController to show a message for three seconds and then fade it out. mainMessageLabel is a UILabel declared in the interface file.

- (void) showTempMessage: (NSString*) message
{
    _mainMessageLabel.text = message;
    _mainMessageLabel.alpha = 1;

    [UIView animateWithDuration: 1
                          delay: 3
                        options: 0
                     animations: ^{
                         _mainMessageLabel.alpha = 0;
                     }
                     completion: ^(BOOL finished) {
                         _mainMessageLabel.text = @"";
                         _mainMessageLabel.alpha = 1;
                     }];
}

The method works fine if I call it at least four seconds after the previous call, but if I call it sooner, when the previous instance is still animating, the label disappears and I have to wait another four seconds until I can call it again to work. Every time I call this method, I want it to stop the previous animation and display the new message for three seconds and fade it out.

I have tried the answers in the other questions here, such as adding UIViewAnimationOptionBeginFromCurrentState to options:, and even adding [_mainMessageLabel.layer removeAllAnimations] to the top of my function, but nothing works. Do you have any suggestions?


Solution

  • The problem is the timing of the completion block (that it fires after the code that cancels the prior animation and resets the label). The easy solution is to just eliminate that completion block altogether (leaving it with alpha of zero is indistinguishable from setting the text to @"" and making it "visible"). Thus:

    _mainMessageLabel.text = message;
    _mainMessageLabel.alpha = 1.0;
    
    [UIView animateWithDuration:1 delay:3 options:0 animations:^{
        _mainMessageLabel.alpha = 0.0;
    } completion:nil];