iosuiviewanimatewithduration

UIView AnimateWithDuration Never Reaches Completion Block


I have this bit of code that I use to switch the root view controller with a nice little animation, it had been working for months... but then randomly stopped working.

UIView snapshot = [self.window snapshotViewAfterScreenUpdates:YES];
[viewController.view addSubview:snapshot];
self.window.rootViewController = viewController;
NSLog(@"check point 1");
[UIView animateWithDuration:0.3 animations:^{
     NSLog(@"check point 2");
    snapshot.layer.opacity = 0;
     NSLog(@"check point 3");
    snapshot.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5);
     NSLog(@"check point 4");
} completion:^(BOOL finished) {
    NSLog(@"check point 5");
    [snapshot removeFromSuperview];
     NSLog(@"check point 6");
}];

I put in these checkpoints, everything through checkpoint 4 triggers.. but 5 and 6 never trigger. So weird to me because even if it failed, the completion block should still trigger.

On the new root view controller that loads, the user's permission to gather his or her location is requested. So maybe when that pop up shows up, it wrecks this transition? It didn't used to though.


Solution

  • The completion block will not call if there is nothing to animate or the transition part already done by some another part of your source code and the code snippet runs on different thread(besides UI thread). Therefore just to illustrate, completion block of below code will never trigger,

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"check point 1");
            [UIView animateWithDuration:10.3 animations:^{
                NSLog(@"check point 4");
            } completion:^(BOOL finished) {
                NSLog(@"check point 5");
                [snapshot removeFromSuperview];
                NSLog(@"check point 6");
            }];
     });
    

    To solve this, Enclose your code within this code,

    dispatch_async(dispatch_get_main_queue(), ^{
        //Your code, This runs on main thread
    });