2013-08-29 19 views
6

Ho trovato diverse domande a questo proposito ma le risposte non risolvono il mio problema.Eliminazione di due controller di visualizzazione modali

Ho due controller che ho presentato utilizzando presentModalViewController.

Ho aggiunto modalTransitionStyle al primo controller chiamato dal controller principale. Il primo controller presentava normalmente il secondo controller (senza stile di transizione).

FirstVC *first = [[FirstVC alloc] initWithNibName:@"FirstVC" bundle:nil]; 
first.modalTransitionStyle = UIModalTransitionStylePartialCurl; 
[self presentModalViewController:first animated:YES]; 

SecondVC *second = [[SecondVC alloc] initWithNibName:@"SecondVC" bundle:nil]; 
[self presentModalViewController:second animated:YES]; 

Questo è il codice che ho usato per andare al MainVC:

[self.presentingViewController.presentingViewController dismissModalViewControllerAnimated:YES]; 

E questo è quello che è successo:

enter image description here

La pagina non ha uncurl. Qual è la ragione per cui sto incontrando questo?

risposta

3

Si dovrebbe presentare i due punti di vista uno dopo l'altro, con questo invito:

[self presentViewController:firstViewController animated:YES completion:^(
    [self presentViewController:secondViewController animated:YES completion:^(

    }]; 
}]; 

questo dovrebbe comportarsi meglio. Inoltre, sappi che dovrai rimuovere entrambi questi viewController in seguito.

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{ 
    [self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^{ 

    }]; 
}]; 
+0

grazie per la risposta. Ma il secondo controller di visualizzazione verrà chiamato solo dopo aver fatto clic su un pulsante all'interno della vista del primo controller. –

+0

ahh, quindi assicurati di rimuoverli entrambi dopo la fine. – HalR

+0

Ciao HalR, la tua risposta mi ha aiutato. Quello che ho fatto è stato pubblicare una notifica all'interno del blocco di completamento. 'code' [self.presentingViewController dismissViewControllerAnimated: NO completion:^{[[NSNotificationCenter defaultCenter] postNotificationName: @" BACKTOMAIN "oggetto: nil];}]; –

2

Sembra che tu stia chiudendo "prima" senza chiudere "secondo".

Il modo consigliato da Apple per farlo è con delega.

Provare a fare del mainVC un delegato del 'primo' in modo che prima possa chiamare un metodo di mainVC per chiudersi. Fai questo dichiarando una proprietà 'delegato' di 'first' e impostandola su mainVC quando 'first' è istanziato. quindi definisci un protocollo 'firstDelegate' in first.h che include alcune funzioni come 'dismissFirst' e quindi importa first.h in mainVC. ora implementa dismissFirst in mainVC per ignorare effettivamente "first" e fare qualsiasi altra cosa tu voglia ora che prima viene visualizzato.

gasp ... ora rendere 'prima' un delegato di 'second' allo stesso modo, e basta fare in modo che la funzione 'dismissSecond' chiami la funzione 'dismissFirst' di mainVC e tutto andrà bene con il mondo.

So che questo è abbastanza complicato ma la delega è un concetto di base di iOS e questo è l'esempio per eccellenza di dove viene utilizzato.

Ecco una buona spiegazione di come funziona. http://chrisrisner.com/31-Days-of-iOS--Day-6%E2%80%93The-Delegate-Pattern

E vi auguro buona fortuna nella vostra ricerca senza fine per comprendere le macchinazioni interne della mente di un ingegnere Apple noto anche come Obj-C.

+1

Va bene ignorare più controller che si sono presentati l'un l'altro in una catena. Se si elimina il primo della catena, tutti gli altri vengono ignorati. In questo caso specifico, il problema deriva dagli stili di presentazione che si infrangono. – rdelmar

+0

Ho risolto il problema utilizzando il codice fornito da HalR e alcune modifiche. Ho aggiunto una notifica per chiudere l'altro controller. –

6

Nei miei esperimenti, sembra che non sia possibile avere una presentazione standard (copertina verticale) dopo un arricciamento parziale e chiuderli entrambi allo stesso tempo, a meno che non si esegua il licenziamento con l'animazione impostata su NO.

Un modo per risolvere questo problema è però di respingere secondVC senza animazione (questo codice è in secondVC):

-(IBAction)dismissSelf:(id)sender { 
    [self dismissViewControllerAnimated:NO completion:nil]; 
} 

Poi nel firstVC respingere di nuovo in viewDidAppear con l'animazione, dopo aver testato che il controller non è essere presentato:

-(void)viewDidAppear:(BOOL)animated { 
    if (![self isBeingPresented]) { 
     [self dismissViewControllerAnimated:YES completion:nil]; 
    } 
} 

Mentre il codice precedente funziona per tornare alla visualizzazione del controller iniziale, vedrete vista di firstVC comparire davanti il ​​ricciolo uncurls. Se non vuoi vederlo, allora l'unico modo che ho trovato per risolverlo era creare un'immagine di secondVC, aggiungerla come (in una vista immagine) una sottoview a firstVC prima di fare il licenziamento di secondVC. Così, per fare questo, il codice in secondVC dovrebbe essere questo, invece (si noti che è necessario creare un collegamento a QuartzCore e importarlo in secondVC per questo lavoro):

-(void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    UIImage *img = [self imageWithView:self.view]; 
    FirstViewController *first = (FirstViewController *)self.presentingViewController; 
    UIImageView *iv = [[UIImageView alloc] initWithFrame:first.view.bounds]; 
    iv.image = img; 
    [first.view addSubview:iv]; 
} 


-(IBAction)dismissSelf:(id)sender { 
    [self dismissViewControllerAnimated:NO completion:nil]; 
} 


- (UIImage *)imageWithView:(UIView *)view { 
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]); 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return img; 
} 
+0

Ho risolto con successo il problema utilizzando [self.presentingViewController dismissViewControllerAnimated: NO completion:^{[[NSNotificationCenter defaultCenter] postNotificationName: @ "BACKTOMAIN" oggetto: nil];}]; Quindi nel controller di ricezione, ho aggiunto [self dismissModalViewControllerAnimated: YES]; Grazie per la risposta anche :) –

0

Ho anche avuto lo stesso dubbio. Ho risolto in altro modo -

Passaggio 1: in una classe globale (singleton) è possibile definire un flag di variabile.

@property (nonatomic) int flag; 

Fase 2: Si supponga di dover respingere second view controller e first view controller e ritorna il Main view controller, mentre respinge il secondo controller della vista è possibile impostare questo valore come supporre 1.

[[Global sharedObject] setFlag:1]; 
[self.navigationController popViewControllerAnimated:YES]; 

Fase 3: In te - (void)viewWillAppear:(BOOL)animated metodo della first view controller è possibile impostare questo metodo -

if([[Global sharedObject] flag] == 1) 
{ 
    [[Global sharedObject] setFlag:0]; 
    [self performSelector:@selector(back) withObject:nil afterDelay:0.5]; 
} 

- (void) back 
{ 
[self.navigationController popViewControllerAnimated:YES]; 
} 

Spero che la tua risposta è risolto usando questo. Se hai ancora dei dubbi, potresti chiedere. Saluti :)

0
- (UIViewController*)topViewController 
{ 
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; 
    while (topController.presentedViewController) { 
     topController = topController.presentedViewController; 
    } 
    return topController; 
} 


- (void)dismissAllModalController{ 

    __block UIViewController *topController = [self topViewController]; 

    while (topController.presentingViewController) { 
     [topController dismissViewControllerAnimated:NO completion:^{ 

     }]; 
     topController = [self topViewController]; 
    } 
} 

Happy Coding :)

0

è necessario utilizzare un unwind segue. Crea un IBAction "vuoto" nel controller della vista che desideri seguire.

@IBAction func unwindToController(segue: UIStoryboardSegue) { 

} 

Quindi andare allo storyboard e selezionare il controller da cui si desidera venire. Nelle icone nella parte superiore di un controller selezionato, il più a sinistra dovrebbe essere un cerchio giallo con al centro un quadratino bianco, ovvero il proprietario del file. Ctrl-Trascina fino all'etichetta "Exit" del controller di visualizzazione a cui desideri eseguire lo svolgimento. L'uscita può essere trovata nella parte inferiore degli alberi dei controller o sullo Storyboard come l'immagine del quadrato rosso più a destra con il quadrato bianco con la freccia a destra al suo interno. Apparirà una finestra di dialogo, seleziona l'azione che hai creato.

Un nuovo "Unwind follow to Exit" apparirà nel controller FROM. Fai doppio clic e assegna un identificatore, ad es. unwindIdentifier

Ora, quando si desidera rilassarsi due controllore, nella vostra dal regolatore, uso:

self.performSegueWithIdentifier("unwindIdentifier", sender:nil) 

che salterà il controllore centrale e distendersi al secondo, mostrando solo l'al controller nell'animazione.

Problemi correlati