Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dismissViewControllerAnimated:completion: not executed

When I call dismissViewControllerAnimated:completion: to dismiss a UIViewController the completion block is never executed when the corresponding view is in the middle of being animated onto the screen (using presentViewController:animated:completion:).

The UIViewController does not even dissappear. It is like dismissViewControllerAnimated:completion: is being ignored.

The following code is a simplified code example because the original is much bigger. The code I have given below simulates a use-case where a network communication error might trigger a view to popup whilst another view is also being popped-up at the same time..

Code example:

NSLog(@"Presenting view");

[self presentViewController:changeLocationViewController animated:YES completion:^{
    NSLog(@"View done presenting");
}];

NSLog(@"Dismissing view");

[self dismissViewControllerAnimated:NO completion:^{
    NSLog(@"View done dismissing");
}];

Log output is:

2013-08-28 16:14:12.162 [1708:c07] Presenting view
2013-08-28 16:14:12.178 [1708:c07] Dismissing view
2013-08-28 16:14:12.583 [1708:c07] View done presenting


Does anyone know how to dismiss the UIViewController in these circumstances?

Thanks in advance.

like image 732
MhaW Avatar asked Aug 28 '13 13:08

MhaW


2 Answers

The reason this code snippet isn't working is because the completion block in these methods are executed at a later time after the animations have completed. You can see this in your logs: "Dismissing view" happens before "View done presenting". Try this instead:

NSLog(@"Presenting view");

[self presentViewController:changeLocationViewController animated:YES completion:^{
    NSLog(@"View done presenting");
    NSLog(@"Dismissing view");

    [self dismissViewControllerAnimated:NO completion:^{
        NSLog(@"View done dismissing");
    }];
}];

EDIT:

If you need to make sure the view is dismissed when the network error happens, try setting a boolean instance variable called networkErrorFound.

When you finish the network connection, set this to YES if an error happens. Then use this code:

[self presentViewController:changeLocationViewController animated:YES completion:^{
    NSLog(@"View done presenting");
    NSLog(@"Dismissing view");

    if (self.networkErrorFound) {
        [self dismissViewControllerAnimated:NO completion:^{
            NSLog(@"View done dismissing");
        }];
    }
}];

That way, it'll wait until it's done presenting to dismiss. You would also need to handle the case that the error happens after the animation is done (for instance, a slow connection that eventually fails), but that's outside the scope of this question.

like image 75
aopsfan Avatar answered Oct 22 '22 06:10

aopsfan


Why dont you dismiss it when its done loading?

[self presentViewController:changeLocationViewController animated:YES completion:^{
    NSLog(@"View done presenting");

    NSLog(@"Dismissing view");

    [self dismissViewControllerAnimated:NO completion:^{
        NSLog(@"View done dismissing");
     }];
}];
like image 24
Yas Tabasam Avatar answered Oct 22 '22 06:10

Yas Tabasam