Chaining the Presentation of Modal View Controllers
I just got my ass handed to me. Thanks Cocoa!
Details…
In the application I am working on currently, there existed the need to present two UIViewControllers modally, one after another.
The first step in enabling this behavior is knowing when one modal closes so I can launch the other. Easy enough, use a notification So I did, and it looks something like this:
// create view controllers MXInputViewController *dialog = [[IMXnputViewController alloc] init]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:dialog]; [dialog release]; // register to be told when the dialog is finished [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(inputViewControllerClosed:) name:MXInputViewControllerClosedNotification object:nil]; // Show dialog modally [[self navigationController] presentModalViewController:navController animated:YES]; [navController release];
And in the MXInputViewControllerL
- (void)viewDidDisappear:(BOOL)animated{
[[NSNotificationCenter defaultCenter] postNotificationName:MXInputViewControllerClosedNotification object:nil];
}
And in the parent view controller:
- (void)inputViewControllerClosed:(NSNotification *)aNotification{
MXInputViewController *secondDialog = [[IMXnputViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:secondDialog];
[secondDialog release];
// Show dialog modally
[[self navigationController] presentModalViewController:navController animated:YES];
[navController release];
}
Should work like a charm, right? Wrong.
What would happen is that deep in the bowels of CoreAnimation, there would be and EXC_BAD_ACCESS thrown when CoreAnimation was executing the callbacks attached to the animation of presenting that view controller. Very hard to debug, and probably something I couldn’t figure out anyway. (The stack trace in Xcode was gray, meaning this crash wasn’t happening in my code).
The solution? Was to delay the presentation of the second view controller using
performSelector:withObject:afterDelay
The final callback code looked like this:
- (void)inputViewControllerClosed:(NSNotification *)aNotification{
[self performSelector:@selector(showViewControllerDelayed) withObject:nil afterDelay:0.0];
}
- (void)showViewControllerDelayed{
MXInputViewController *secondDialog = [[IMXnputViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:secondDialog];
[secondDialog release];
// Show dialog modally
[[self navigationController] presentModalViewController:navController animated:YES];
[navController release];
}
Yeah, you saw that correctly.. a ZERO second delay. THAT fixed it.
Weird
-
jeffrock liked this
-
jamiepinkham posted this