does animateWithDuration:animations: block main thread?

30,664

Solution 1

Animating with blocks doesn't block the main thread. I think the behavior you're seeing is because, by default, user interaction is disabled duration animation with the new block calls. You can override this by passing UIViewAnimationOptionAllowUserInteraction (calling animationWithDuration:delay:options:animations:completion), like this:

-(IBAction) fadeUsingBlock {
    NSLog(@"V1: Clicked ...");
    [myLabel setAlpha:1.0];
    [UIView animateWithDuration:1.5 
                          delay:0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:^{
                         [myLabel setAlpha:0.0];
                     }
                     completion:nil];
}

Solution 2

For animateWithDuration:, the class reference doesn't say anything about threading, so I am not sure.

For beginAnimations:context: and commitAnimation:, yeah, they run in a separate thread UIView class Reference.

Some of the property changes to view objects can be animated—for example, setting the frame, bounds, center, and transform properties. If you change these properties in an animation block, the changes from the current state to the new state are animated. Invoke the beginAnimations:context: class method to begin an animation block, set the properties you want animated, and then invoke the commitAnimations class method to end an animation block. The animations are run in a separate thread and begin when the application returns to the run loop. Other animation class methods allow you to control the start time, duration, delay, and curve of the animations within the block.

Share:
30,664
fuzzygoat
Author by

fuzzygoat

Apple Development @ Fuzzygoat, A digital nomad adventuring in one possible future.

Updated on July 09, 2022

Comments

  • fuzzygoat
    fuzzygoat almost 2 years

    I have connected the two methods below to separate buttons in my UI but have noticed that after pressing the "VERSION 1" button that I could not press the button again until the animation duration within the method had ended. My understanding was that the animation uses its own thread so as not to block the main application.

    // VERSION 1
    -(IBAction)fadeUsingBlock {
        NSLog(@"V1: Clicked ...");
        [myLabel setAlpha:1.0];
        [UIView animateWithDuration:1.5 animations:^{
            [myLabel setAlpha:0.0];
        }];
    }
    

    The older style version (below) does allow the button to be repressed before the animation timer ends, simply resetting the timer to start again. Should these both work the same, am I missing something or has there been a change in operation between 3.2 and 4?

    // VERSION 2
    -(IBAction)fadeUsingOld {
        NSLog(@"V2: Clicked ...");
        [myLabel setAlpha:1.0];
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:1.5];
        [myLabel setAlpha:0.0];
        [UIView commitAnimations];
    }
    

    Cheers gary

  • fuzzygoat
    fuzzygoat almost 14 years
    Ah that makes sense, I had missed that option in the docs, I will look it up. Many thanks, much appreciated.
  • runmad
    runmad about 13 years
    Thanks for this. Damn, this was bugging me. It's actually quite annoying it's not on by default, because it does say it blocks interaction with the view being animated, but in fact it blocks the entire UI!
  • BJ Homer
    BJ Homer over 12 years
    Man, wouldn't it be nice if this were fixed in the upcoming iOS 5.0... <wink>