I had the same issue and I found a clean solution avoid using dispatch_async or dispatch_after.
Simply, as described by the exception, you are trying to dismiss a view controller while the presenting transition is still in progress.
This means that once the
- presentViewController:animated:completion:
completion block is called, and you invoke the dismiss, the transitioning is not completed.
Starting from iOS 7 transitioning UIViewController has a new method available
- transitionCoordinator
The transitionCoordinator gives you the
chance to enqueue a completion block as soon as the transition completes.
The object returned by the method conforms the UIViewControllerTransitionCoordinator protocol. Knowing that the solution is really simple.
After the invocation of
- presentViewController:animated:completion:
the transition coordinator is properly configured by the framework.
Use
- animateAlongsideTransition:completion:
on it to send the proper completion block.
Here a little code snippet that better explain the solution
void(^completion)() = ^() {
[modalViewController dismissViewControllerAnimated:YES completion:nil];
};
// This check is needed if you need to support iOS version older than 7.0
BOOL canUseTransitionCoordinator = [viewController respondsToSelector:@selector(transitionCoordinator)];
if (animated && canUseTransitionCoordinator)
{
[viewController presentViewController:modalViewController animated:animated completion:nil];
[viewController.transitionCoordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
completion();
}];
}
else
{
[viewController presentViewController:modalViewController animated:animated completion:completion];
}