EDIT: El mecanismo "correcto" para hacer esto en iOS5 + sería utilizar el método – dismissViewControllerAnimated:completion:
, y presentar el controlador de vista secuencial desde el bloque de finalización.
El ViewController que está siendo mostrado de forma modal tendrá su viewDidDisappear: animada: método llama una vez que el modal-despido-animación es completa.AFIK este es el único lugar donde puedes enlazar para iniciar un presentModalViewController siguiente: animado: llamada.
Tengo una clase que utilizo para presentar controladores de vistas modales e implementa la lógica que está buscando mediante una devolución de llamada al controlador de vista de presentación una vez que se completa el despido. Para usar esta clase, simplemente alloc/init una instancia y presente usando la función presenteViewController: animated: call. Aplicar el siguiente método en el controlador de vista de presentación:
- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
Esto se llama a la vez el controlador de vista modal se ha ido, y se puede presentar un nuevo controlador de vista modal en este momento.
Una cosa buena también, ya que esta clase es una especialización de UINavigationController, puede configurar la barra de navegación como se desee. La clase también tiene una lógica incorporada para mostrar un botón de descartar, como quieras.
Aquí está la definición de clase:
@protocol TSModalViewControllerDelegate
- (void) modalViewControllerDidDismiss: (UIViewController*) modalViewController;
@end
@interface TSModalViewController : UINavigationController
{
UIViewController* _originalParentViewController;
}
@property BOOL dismissButtonHidden;
- (id) initWithViewController: (UIViewController*) vc;
- (id) initWithClass: (Class) c;
- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
@end
Y la implementación de la clase:
@implementation TSModalViewController
@synthesize dismissButtonHidden;
- (id) initWithViewController: (UIViewController *)vc
{
return [super initWithRootViewController: vc];
}
- (id) initWithClass:(Class)c
{
UIViewController* vc = [[[c alloc] init] autorelease];
return [self initWithViewController: vc];
}
- (id) initWithClass: (Class) c nibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
UIViewController* vc = [[[c alloc] initWithNibName:nibNameOrNil bundle:nibBundleOrNil] autorelease];
return [self initWithViewController: vc];
}
- (void) viewDidAppear: (BOOL) animated
{
[super viewDidAppear: animated];
[_originalParentViewController release];
_originalParentViewController = [self.parentViewController retain];
if (!self.dismissButtonHidden)
{
UIBarButtonItem* dismissButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemStop
target: self
action: @selector(onDismiss:)] autorelease];
UIViewController* rootViewController = [self.viewControllers objectAtIndex:0];
rootViewController.navigationItem.leftBarButtonItem = dismissButton;
self.navigationBarHidden = NO;
}
}
- (void) viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear: animated];
if ([_originalParentViewController respondsToSelector: @selector(modalViewControllerDidDismiss:)])
{
[_originalParentViewController performSelector: @selector(modalViewControllerDidDismiss:) withObject: self];
}
}
- (void) dismissModalViewControllerAnimated:(BOOL)animated
{
return [self.parentViewController dismissModalViewControllerAnimated: animated];
}
- (void) onDismiss: (id) sender
{
[self.parentViewController dismissModalViewControllerAnimated: YES];
}
- (void) didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void) viewDidUnload
{
[super viewDidUnload];
}
- (void)dealloc
{
[_originalParentViewController release];
[super dealloc];
}
@end
y, aquí es cómo se puede usar (en el contexto de algún controlador de vista normal):
- (void) onShowIt:(id)sender
{
TSModalViewController* mvc = [[[TSModalViewController alloc] initWithClass: [MyModalViewController class] nibName: @"MyModalViewController" bundle:nil] autorelease];
mvc.dismissButtonHidden = YES; // set to no if you don't want an "automatic" close button
[self presentModalViewController: mvc animated: YES];
}
y, aquí está el método de devolución de llamada de salida, que presenta un nuevo controlador de vista modal:
- (void) modalViewControllerDidDismiss:(UIViewController *)modalViewController
{
MyModalViewController* vc = [[[MyModalViewController alloc] initWithNibName: @"MyModalViewController" bundle:nil] autorelease];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
TSModalViewController* mvc = [[[TSModalViewController alloc] initWithViewController: vc] autorelease];
[self presentModalViewController: mvc animated: YES];
}
Por qué no utilizar el modal controlador de vista que cambia su punto de vista? Dos controladores de vista modal seguidos serían un poco molestos. – bpapa
Si son "consecutivos", considere usar la navegación. –
¿Estás 100% seguro de que el descarte de la 1ª vista modal y la apertura de la 2ª se realizan en el contexto del hilo principal? – yonel