2011-12-29 17 views
9

ho vista login presentato come un Model-View-Controller e ho una vista registro presentato come un NavigationControlloer su di esso:Nascondi tutti i controller di vista modale

Accesso (Model-View-Controller) ----> Register (navigationController)

sto presentando la vista Register (CreateAccount) al LoginView come segue:

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]; 

il controller di accesso ha il NSURLConnectionDelegate per stand login e registro. quando finishs registrazione ho semplicemente chiamare il

[self dismissModalViewControllerAnimated:YES]; 

che respingere solo la visualizzazione di registrazione.

voglio chiudere la vista di login anche così posso tornare alla mia applicazione principale.

+0

Si prega di chiarire come si sta presentando la vista di registrazione. È un'altra vista modale? –

+0

ho modificato il post :) – Kassem

risposta

19

Partenza mia risposta a una domanda simile qui: Dismissing ModalViewController of ModalViewController

Sto usando più o meno la stessa cosa di te nella mia app, e questa soluzione funziona per me. Assicurati di leggere anche i commenti, dal momento che uno dei riferimenti è cambiato con iOS5.

Edit: Al fine di respingere una vista modale che viene presentato su un altro vista modale, è necessario chiamare dismissModalViewControllerAnimated: sul genitore del genitore.

iOS < 5,0

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

iOS 5.0+ (deve cambiare tutti i riferimenti a parentViewController a presentingViewController)

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

+1 Questo ha funzionato magnificamente per me. Sarebbe bello se la soluzione fosse inclusa anche qui. –

+1

@JasonGeorge modificato per includere risposta ... grazie :) – superjessi

+2

Attenzione: _dismissModalViewControllerAnimated_ ** deprecato ** (in iOS 6.0), utilizzare _dismissViewControllerAnimated: completamento: _. – CFIFok

23

Chiamando dismissModalViewController, se il controller di visualizzazione corrente non ha presentato alcun controller modale, chiamare invece il metodo su suo padre. Chiamando il metodo su un controller di visualizzazione si eliminerà tutto il controller di visualizzazione modale presentato su quel controller. Per illustrare:

Se si dispone di tre controller di visualizzazione: vc1, vc2 e vc3 e vc1 è il controller di visualizzazione principale/attualmente utilizzato.

  1. In vc1 si presenta modale vc2. In vc2 chiami poi il congedo, perché non ci sono vcs modali presentati da vc2, il messaggio di respingimento è passato al genitore (vc1) che congeda vc2, e tu torni a vc1.

  2. In vc1 si presenta modale vc2, quindi da vc2 presente modale vc3. Chiamando licenziamento in vc3 invierà il messaggio al suo genitore (vc2) che eliminerà vc3. Per respingere vc2 e vc3 allo stesso tempo, è necessario chiamare congestione in vc1, questo eliminerà tutti i controller di visualizzazione modale (entrambi). Se si respinge l'animazione, solo il primo sarà animato.

Uno dei modi migliori per risolvere questo problema è l'utilizzo di un controller di navigazione. Ad esempio, invece di usare inizialmente modalViews per presentare la vista di accesso, usa lo stesso navigationViewcontroller. Se è necessario presentare la pagina di registrazione. Spingi quella vista. Se è necessario accedere alla vista iniziale (ad eccezione di loginView o registrationView), utilizzare il metodo popToRootViewControllerAnimated in navigationViewcontroller.

+3

+1 Molto utile per capire il flusso vc. –

0

dismissModalViewControllerAnimated: elimina tutti i controller di visualizzazione modale presentati in cima al mittente. Per respingere indietro al controller della vista che ha presentato il controller di accesso, mantenere un riferimento ad esso e respingere come segue:

[loginController dismissModalViewController:animated] 

Questo è il modo forza bruta di farlo. Nella mia app, dove ho fatto qualcosa di simile, postò varie notifiche corrispondenti allo stato della sessione (ad esempio login) e il mio controller di login osserva queste notifiche e si congeda in modo appropriato.

1

Il problema principale a portata di mano è che il controller della vista di accesso è completamente inconsapevole quando la vista di registrazione viene chiusa e possiamo gestirla con delega.

Prima dichiarare un protocollo e una proprietà delegato sul controller della vista di registrazione.

@protocol CreateAccountDelegate; 

@interface CreateAccount : UIViewController 

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

@end 

@protocol CreateAccountDelegate <NSObject> 

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

@end 

Quindi, rendere il controller della vista di accesso il delegato del controller di registrazione.

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

e implementare -createAccountViewControllerDidFinish:

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

Infine, quando si elimina dal all'interno del controller di registrazione, il messaggio del delegato di informarlo se il licenziamento imminente.

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

Ora, dopo aver detto tutto questo. Posso suggerire una modifica al tuo design? Presenterei il controller di visualizzazione login come parte di un controller di navigazione sin dall'inizio. Quindi se l'utente sceglie di registrarsi, basta premere la vista di registrazione sul controller. In questo modo, indipendentemente da dove ti allontani, dovrai solo chiudere il controller di navigazione principale.

0

Luogo questo metodo nella vostra applicazione delegato e rimuoverà tutti i controller di vista che hanno un VisualController presentato che significa che sono stati presentati modalmente

-(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

ha smesso di funzionare per me in iOS 7 – obiwahn

+0

quindi hai un altro problema, appena testato in xcode con Target di sviluppo impostato su 7.0 e funzionava ancora. Assicurati di chiamare questo metodo in un NSObject che implementa il protocollo UIApplicationDelegate e che hai impostato self.window.rootViewController.Non sto usando lo storyboard per progetto – zurbergram

+0

Ho cambiato il ritardo a 0,75, quindi ha funzionato. Ho compilato un'applicazione iOS 6 per iOS 7. Forse hanno cambiato i tempi perché prima funzionava con 0.5 tempi. – obiwahn

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

lavorato per respingere tutto in iOS 7

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

Respingere tutti i controller ad eccezione RootViewController ..

Problemi correlati