2013-02-18 13 views
6

Ho creato due UIViewControll che viene presentato come modale. Diciamo per i primi 5 tentativi, il modal presenterà normalmente ma poi mi darà una:Avviso su due controller di navigazione presentato come modale

Warning: Attempt to dismiss from view controller <UINavigationController: 0x76a8450> while a presentation or dismiss is in progress! 

seguito è riportato il codice per respingere il controller della vista corrente e la presentazione di un altro

[customAlertLoad dismissViewControllerAnimated:NO completion:^{ 
    CustomAlertMsg *cust = [[CustomAlertMsg alloc] init]; 
    cust.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    cust.modalPresentationStyle = UIModalPresentationFormSheet; 
    cust.delegate = self; 

    [self.navigationController presentModalViewController:cust animated:YES]; 
    cust.view.superview.frame = CGRectMake(0, 0, 458, 230); 
    cust.view.superview.center = self.view.center; 
}]; 

Qualsiasi aiuto sarà essere molto apprezzato

+0

Cosa le isBeingPresented' o '' proprietà isBeingDismissed' del controller della vista suggeriscono nel blocco di completamento? – neeraj

+0

Ho provato a testare isBeingDismissed ma il risultato è sempre NO quindi l'avviso continua a essere visualizzato. – Rye

+0

Hai controllato quale VC è questo 'UINavigationController: 0x76a8450'? 'customAlertLoad' o' cust'? – neeraj

risposta

2

modificare

ho appena ricordato un altro problema simile da un paio di settimane fa. Stai riscontrando una condizione di competizione, che può probabilmente essere risolta utilizzando GCD (Grand Central Dispatch). Questo è simile alla soluzione suggerita da @ rakesh, ma meno pericolosa. (Usare i timer è una cattiva pratica per gestire una condizione di competizione, anche se in molte lingue chiamare un metodo con un'attesa del timer di 0 secondi è un trucco usato per mettere quella chiamata di metodo alla fine dello stack di chiamate, ovvero renderla asincrona). Apple fornisce un meccanismo per questo.

vorrei provare a fare questo lieve modifica:

[customAlertLoad dismissViewControllerAnimated:NO completion:^{ 
          dispatch_async(dispatch_get_main_queue(), ^(void) { 
            CustomAlertMsg *cust = [[CustomAlertMsg alloc] init]; 
            cust.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
            cust.modalPresentationStyle = UIModalPresentationFormSheet; 
            cust.delegate = self; 

            [self.navigationController presentModalViewController:cust animated:YES]; 
            cust.view.superview.frame = CGRectMake(0, 0, 458, 230); 
            cust.view.superview.center = self.view.center; 
           }); 
         }]; 

La chiamata al dispatch_async mette il blocco alla fine lo stack di esecuzione. Non è possibile per questo eseguire prima che il modal sia stato rimosso. Ciò consente anche l'animazione sul licenziamento e la presentazione dei due modali.

Devo tuttavia menzionare che in questo particolare problema, questo è un hack. Hai un problema da qualche altra parte. Se riproduco la tua configurazione in un progetto di test, posso creare/eliminare tutte le modali che voglio dai blocchi di completamento senza incorrere nel tuo errore (a patto che il codice di licenziamento venga chiamato da un callback del delegato personalizzato utilizzato per chiudere il modale , come suggerisce la mela). Guarderei attraverso il tuo carico di avvisi personalizzati e codice di classi di avvisi personalizzati.

modificare fine

Questo può non essere lo stesso tuo problema, ho sperimentato questo problema prima con popovers dopo lo spostamento il mio codice di base ad arco. C'erano cose strane che accadevano dove il mio Popover veniva rilasciato troppo presto, o trattenuto troppo a lungo. La soluzione era creare una variabile di istanza per contenere il popover e gestirla manualmente. Poi tutto ha iniziato a funzionare honkey dory.

Quindi vorrei fare:

@interface YourClass:UIViewController 

@property (nonatomic,strong) CustomAlertMsg *cust; 

@end 


@implementation YourClass 

... Codey Code.... 

-(void)pushView{ 
    // For the sake of sanity, nil the modal here 
    if(self.cust != nil) self.cust = nil; 
    self.cust = [[CustomAlertMsg alloc] init]; 
    self.cust.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    self.cust.modalPresentationStyle = UIModalPresentationFormSheet; 
    self.cust.delegate = self; 

    [self.navigationController presentModalViewController:self.cust animated:YES]; 
    self.cust.view.superview.frame = CGRectMake(0, 0, 458, 230); 
    self.cust.view.superview.center = self.view.center; 
} 

// Then where you dismiss it, or in the delegate callback that is 
// called when you dismiss it, if you are using one anyway, 
// nil it out 
- (void)methodThatDismissesModal 
{ 
    [self dismissModalViewControllerAnimated:YES]; 
    // This is pretty important 
    if(self.cust != nil) self.cust = nil; 
} 

... Codey Code.... 

@end 
-1

Prova questo,

[customAlertLoad dismissViewControllerAnimated:NO completion:^{ 

    [self performSelector:@selector(pushView) withObject:ni afterDelay:0.4]; 
} 


-(void)pushView{ 
    CustomAlertMsg *cust = [[CustomAlertMsg alloc] init]; 
    cust.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    cust.modalPresentationStyle = UIModalPresentationFormSheet; 
    cust.delegate = self; 

    [self.navigationController presentModalViewController:cust animated:YES]; 
    cust.view.superview.frame = CGRectMake(0, 0, 458, 230); 
    cust.view.superview.center = self.view.center; 
} 
+0

ancora senza fortuna. ho già provato a impostare l'intervallo su 1 – Rye

+2

facendo affidamento sui ritardi per gestire le condizioni di gara è una cattiva pratica ... – nielsbot

1

provare a cambiare a questo:

[self.navigationController presentModalViewController:cust animated:NO]; 
+0

Questo sta funzionando bene, ma il layout della modal è incasinato. – Rye

1

Forse provare respinto dal controller di navigazione, invece di customAlertLoad:

[self.navigationController dismissViewControllerAnimated:NO completion:^{ 

    CustomAlertMsg *cust = [[CustomAlertMsg alloc] init]; 
    cust.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 
    cust.modalPresentationStyle = UIModalPresentationFormSheet; 
    cust.delegate = self; 

    [self.navigationController presentModalViewController:cust animated:YES]; 
    cust.view.superview.frame = CGRectMake(0, 0, 458, 230); 
    cust.view.superview.center = self.view.center; 

}]; 
2

Come l'errore-messaggio dice, il problema appare durante congedando. Quindi non è lo presentModalViewController a causare il tuo problema, è lo dismissViewControllerAnimated.

Se potessi incollare un contesto per quella chiamata, potremmo trovare una soluzione.

Problemi correlati