2011-12-29 18 views
9

he presentado una vista de inicio de sesión como un Modelo-Vista-Controlador y tengo una vista de registro presentada como una NavigationControlloer encima de él:Ocultar controladores de vista modal

Usuario (Modelo-Vista-Controlador) ----> Registro (NavigationController)

que estoy presentando la vista Registro (CreateAccount) en el LoginView de la siguiente manera:

createAccount= [[CreateAccount alloc] initWithNibName:@"CreateAccount" bundle:nil]; 

navController = [[UINavigationController alloc] initWithRootViewController:createAccount]; 

UIBarButtonItem *cancelButtun=[[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(HideMe)]; 

UIBarButtonItem *registerButtun=[[UIBarButtonItem alloc]initWithTitle:@"Register" style:UIBarButtonItemStyleBordered target:self action:@selector(Register)]; 

createAccount.navigationItem.leftBarButtonItem = cancelButtun; 
createAccount.navigationItem.rightBarButtonItem=registerButtun; 
[email protected]"Create Account"; 

[self presentModalViewController:navController animated:YES]; 

el controlador de acceso tiene la NSURLConnectionDelegate para la cabina de la entrada y el registro. cuando finishs de registro i simplemente llaman la

[self dismissModalViewControllerAnimated:YES]; 

que despedir sólo la vista de registro.

Quiero descartar la vista de inicio de sesión también para que pueda volver a mi aplicación principal.

+0

Por favor, aclarar la forma en que está presentando la vista de registro. ¿Es otra vista modal? –

+0

edité la publicación :) – Kassem

Respuesta

19

Salida mi respuesta a una pregunta similar aquí: Dismissing ModalViewController of ModalViewController

estoy usando más o menos lo mismo que usted en mi aplicación, y esta solución funciona para mí. Por favor, asegúrese de leer los comentarios también, ya que una de las referencias cambió con iOS5.

Editar: Con el fin de descartar una vista modal que se presenta sobre otro punto de vista modal, usted tiene que llamar dismissModalViewControllerAnimated: en la matriz de la matriz.

iOS < 5,0

[[[self parentViewController] parentViewController] dismissModalViewControllerAnimated:YES]; 

iOS 5.0 o superior (debe cambiar todas las referencias a parentViewController a presentingViewController)

[[[self presentingViewController] presentingViewController] dismissModalViewControllerAnimated:YES]; 
+1

+1 Esto funcionó maravillosamente para mí. Sería bueno si la solución se incluyó aquí también. –

+1

@JasonGeorge editado para incluir respuesta ... gracias :) – superjessi

+2

Tenga cuidado: _dismissModalViewControllerAnimated_ ** obsoleto ** (en iOS 6.0), use _dismissViewControllerAnimated: completion: _ en su lugar. – CFIFok

23

Llamando a dismissModalViewController, si el controlador de vista actual no presenta ningún controlador modal, llame al método en su elemento primario en su lugar. Llamar al método en un controlador de vista desestimará todos los controladores de vista modal presentados a ese controlador. Para ilustrar:

Si tiene tres controladores de vista: vc1, vc2 y vc3 y vc1 es el controlador de vista principal/utilizado actualmente.

  1. En vc1 presenta modal vc2. En vc2, a continuación, se llama a descartar, porque no hay vcs modales presentados desde vc2, el mensaje de descarte se pasa al padre (vc1) que rechaza vc2, y usted está de vuelta en vc1.

  2. En vc1 presenta modal vc2, luego de vc2 presente modal vc3. La llamada para descartar en vc3 enviará el mensaje a su principal (vc2) que rechazará vc3. Para cerrar vc2 y vc3 al mismo tiempo, debe llamar a dismiss en vc1, esto descartará todos los (ambos) controladores de vista modal. Si descarta animado, solo el primero será animado.

Una de las mejores maneras de resolver esto es utilizar un controlador de navegación de ida y vuelta. es decir, en lugar de usar modalViews inicialmente para presentar la vista de inicio de sesión, use navigationViewcontroller allí mismo. Si necesita presentar la página de registro. Empuja esa vista. Si necesita ir a la vista inicial (es decir, aparte de loginView o registrationView), utilice el método popToRootViewControllerAnimated en navigationViewcontroller.

+3

+1 Muy útil para comprender el flujo de vc. –

0

dismissModalViewControllerAnimated: descarta todos los controladores de vista modal presentados en la parte superior del remitente. Para descartar de nuevo al controlador de vista que presenta el controlador de acceso, mantener una referencia a ella y despedir de la siguiente manera:

[loginController dismissModalViewController:animated] 

Esta es la forma en la fuerza bruta de hacerlo. En mi aplicación, donde hice algo similar, publico varias notificaciones correspondientes al estado de la sesión (por ejemplo, inicio de sesión) y mi controlador de inicio de sesión observa esas notificaciones y se descarta adecuadamente.

1

El principal problema es que el controlador de vista de inicio de sesión no está al tanto de cuándo se descarta la vista de registro y podemos manejar eso con la delegación.

Primero declare un protocolo y una propiedad de delegado en el controlador de vista de registro.

@protocol CreateAccountDelegate; 

@interface CreateAccount : UIViewController 

@property (nonatomic, assign) id <CreateAccountDelegate> delegate; 

@end 

@protocol CreateAccountDelegate <NSObject> 

- (void)createAccountViewControllerDidFinish:(CreateAccount *)controller; 

@end 

A continuación, haga que el controlador de vista de inicio de sesión sea el delegado del controlador de registro.

createAccount = [[CreateAccount alloc] initWithNibName:@"CreateAccount" bundle:nil]; 
createAccount.delegate = self; 

e implementar -createAccountViewControllerDidFinish:

- (void)createAccountViewControllerDidFinish:(CreateAccount *)controller 
{ 
    [self dismissModalViewControllerAnimated:YES]; 
} 

Por último, cuando se despida desde dentro del controlador de registro, el delegado mensaje que le informe si su inminente despido.

[self.delegate createAccountViewControllerDidFinish:self]; 
[self dismissModalViewControllerAnimated:YES]; 

Ahora, habiendo dicho todo eso. ¿Puedo sugerir una alteración a su diseño? Presentaría el controlador de vista de inicio de sesión como parte de un controlador de navegación desde el principio. Luego, si el usuario elige registrarse, simplemente presione la vista de registro en el controlador. De esta forma, no importa desde dónde descarte, solo tendrá que descartar el controlador de navegación principal.

0

Coloque este método en el delegado de la aplicación y se eliminará todos los controladores de vista que tienen un ViewViewController presentado que significa que se presentaron modally

-(void)dismissModalViews 
{ 
    if (self.window.rootViewController.presentedViewController) { 
     [self.window.rootViewController.presentedViewController dismissViewControllerAnimated:NO completion:nil]; 
     [self performSelector:@selector(dismissModalViews) withObject:nil afterDelay:0.5]; 
    } 
} 
+0

dejó de funcionar para mí en iOS 7 – obiwahn

+0

y luego tiene otro problema, acaba de probar en xcode con el objetivo de desarrollo establecido en 7.0 y todavía funcionaba. Asegúrese de estar llamando a este método en un NSObject que implementa el protocolo UIApplicationDelegate y que ha establecido self.window.rootViewController.No estoy usando el guión gráfico para el proyecto – zurbergram

+0

Cambié la demora a 0,75 y funcionó. Recopilé una aplicación iOS 6 para iOS 7. Tal vez cambiaron los tiempos porque antes funcionaba con tiempo 0.5. – obiwahn

-2
while(self.presentedViewController) 
     [self.presentedViewController dismissViewControllerAnimated:NO completion:nil]; 

trabajado para despedir a todos en iOS 7

0
[[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissViewControllerAnimated:true completion:nil]; 

Descartar todos los controladores excepto RootViewController ..

Cuestiones relacionadas