"L'applicazione ha tentato di presentare modalmente un controller attivo"?


100

Mi sono appena imbattuto in un arresto anomalo che mostrava un NSInvalidArgumentExceptioncon questo messaggio su un'app che non lo faceva prima.

L'applicazione ha tentato di presentare in modo modale un controller attivo UITabBarController: 0x83d7f00.

Ho un UITabBarControllerche creo nel AppDelegatee gli do l'array di UIViewControllers.

Uno di loro voglio presentare in modo modale quando viene toccato. L'ho fatto implementando il metodo delegato

- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController

Se quel view controller è della classe di quello che voglio presentare in modo modale, restituisco NO e lo faccio

[tabBarController presentModalViewController:viewController animated:YES];

E ora ricevo quell'errore, il che sembra significare che non puoi presentare in modo modale un controller di visualizzazione attivo da qualche altra parte (nella barra delle schede ...) Dovrei dire che sono su XCode 4.2 Developer Preview 7, quindi questo è iOS 5 (conosco l'NDA, ma penso di non fornire dettagli proibiti). Al momento non ho un'installazione XCode per verificare se questo si blocca durante la compilazione con l'SDK di iOS4, ma sono quasi completamente sicuro che non sia così.

Volevo solo chiedere se qualcuno ha riscontrato questo problema o ha qualche suggerimento


Prima di iOS 5, questo non sollevava un'eccezione, ma non restituiva nulla. Da iOS 5 in poi, questo comando solleva un'eccezione.
Frédéric Adda

Risposte:


103

Supponiamo di avere tre controller di visualizzazione istanziati in questo modo:

UIViewController* vc1 = [[UIViewController alloc] init];
UIViewController* vc2 = [[UIViewController alloc] init];
UIViewController* vc3 = [[UIViewController alloc] init];

Li hai aggiunti a una barra delle schede come questa:

UITabBarController* tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:[NSArray arrayWithObjects:vc1, vc2, vc3, nil]];

Ora stai cercando di fare qualcosa del genere:

[tabBarController presentModalViewController:vc3];

Questo ti darà un errore perché quel controller della barra delle schede ha una presa mortale sul controller della vista che gli hai dato. Non è possibile aggiungerlo all'array di controller di visualizzazione sulla barra delle schede oppure non è possibile presentarlo in modo modale.

Apple si aspetta che tu tratti i loro elementi dell'interfaccia utente in un certo modo. Questo è probabilmente sepolto da qualche parte nelle Linee guida dell'interfaccia umana come un "non farlo perché non ci aspettiamo che tu voglia mai farlo".


6
Il fatto è che questo non era assolutamente un problema prima di iOS 5, quindi la mia preoccupazione! Quello che ho fatto è stato aggiungere un UIViewController fittizio alla barra delle schede e presentare in modo modale l'istanza della sottoclasse del controller di visualizzazione effettiva.
Javier Soto

1
@Iswank, ora in iOS 6, per rendere le cose "più facili", hanno deprecato presentModalViewController causando tutti i tipi di problemi di rotazione ... devi usare presentViewController: animated: completamento e controllare come la tua app sta gestendo le modifiche
whyoz

15

Ho lo stesso problema. Provo a presentare il controller di visualizzazione subito dopo averlo ignorato.

[self dismissModalViewControllerAnimated:YES];

Quando provo a farlo senza animazione funziona perfettamente, quindi il problema è che il controller è ancora vivo. Penso che la soluzione migliore sia usare dismissViewControllerAnimated:completion:per iOS5


Non riesce se lo chiudi animato perché quando vuoi presentare di nuovo il controller di visualizzazione modale, è ancora modale sullo schermo, essendo animato.
Pascal

2
È deprecato in IOS 6.0
Sumit Kumar Saha

12

Nel mio caso stavo cercando di presentare il viewController (ho il riferimento del viewController nel TabBarViewController) da diversi controller di visualizzazione e si è bloccato con il messaggio sopra. In tal caso per evitare di presentare puoi usare

viewController.isBeingPresented

!viewController.isBeingPresented {
          // Present your ViewController only if its not present to the user currently.
}

Potrebbe aiutare qualcuno.


funziona solo in viewWillappperar ma quando devo controllarlo prima di presentare viewController che è già presentato, restituisce sempre false.
guru

1
Non funziona per me. Ottiene ancora un arresto anomalo dell'app. (! viewController.presentingViewController) ha risolto il problema.
Argus

3

Ho avuto lo stesso problema, l'ho risolto. Puoi provare questo codice:

[tabBarController setSelectedIndex:1];
[self dismissModalViewControllerAnimated:YES];

2

Lo stesso errore si è verificato a me quando ho provato a presentun controller di visualizzazione figlio invece del suo UINavigationViewControllergenitore


0

Basta rimuovere

[tabBarController presentModalViewController:viewController animated:YES];

e tieni

[self dismissModalViewControllerAnimated:YES];

questo dà un avviso deprecato ... quindi qual è l'alternativa a questo?
Kirtikumar A.

Qui ho usato [blockSelf dismissViewControllerAnimated: YES completamento: nil];
Kirtikumar A.

0

Invece di usare:

self.present(viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?)

Puoi usare:

self.navigationController?.pushViewController(viewController: UIViewController, animated: Bool)

0

Nel mio caso, stavo presentando il rootViewControllerdi un UINavigationControllerquando avrei dovuto presentare lo UINavigationControllerstesso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.