"L'application a essayé de présenter modalement un contrôleur actif"?


100

Je viens de tomber sur un crash montrant un NSInvalidArgumentExceptionavec ce message sur une application qui ne le faisait pas auparavant.

L'application a tenté de présenter modalement un contrôleur actif UITabBarController: 0x83d7f00.

J'ai un UITabBarControllerque je crée dans le AppDelegateet lui donne le tableau de UIViewControllers.

L'un d'entre eux que je souhaite présenter de manière modale lorsque j'appuie dessus. Je l'ai fait en implémentant la méthode des délégués

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

Si ce contrôleur de vue est de la classe de celui que je veux présenter modalement, je retourne NON et fais

[tabBarController presentModalViewController:viewController animated:YES];

Et maintenant, j'obtiens cette erreur, ce qui semble signifier que vous ne pouvez pas présenter modalement un contrôleur de vue qui est actif ailleurs (dans la barre d'onglets ...) Je devrais dire que je suis sur XCode 4.2 Developer Preview 7, donc c'est iOS 5 (je connais la NDA, mais je pense que je ne donne aucun détail interdit). Je n'ai actuellement pas d'installation XCode pour tester si cela plante la compilation avec le SDK iOS4, mais je suis presque entièrement sûr que ce n'est pas le cas.

Je voulais seulement demander si quelqu'un a rencontré ce problème ou a des suggestions


Avant iOS 5, cela ne soulevait pas d'exception, mais ne renvoyait rien. À partir d'iOS 5, cette commande lève une exception.
Frédéric Adda

Réponses:


103

Supposons que vous ayez trois contrôleurs de vue instanciés comme ceci:

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

Vous les avez ajoutés à une barre d'onglets comme celle-ci:

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

Maintenant, vous essayez de faire quelque chose comme ceci:

[tabBarController presentModalViewController:vc3];

Cela vous donnera une erreur car ce contrôleur de barre d'onglets a une emprise mortelle sur le contrôleur de vue que vous lui avez donné. Vous pouvez soit ne pas l'ajouter au tableau des contrôleurs de vue dans la barre d'onglets, soit ne pas le présenter de manière modale.

Apple attend de vous que vous traitiez leurs éléments d'interface utilisateur d'une certaine manière. Ceci est probablement enterré quelque part dans les Directives de l'Interface Humaine comme un "ne faites pas cela parce que nous ne nous attendons pas à ce que vous vouliez jamais faire cela".


6
Le fait est que ce n'était absolument aucun problème avant iOS 5, d'où mon inquiétude! Ce que j'ai fait a été d'ajouter un UIViewController factice à la barre d'onglets et de présenter de manière modale l'instance de sous-classe de contrôleur de vue réelle.
Javier Soto le

1
@Iswank, maintenant dans iOS 6, pour rendre les choses «plus faciles», ils ont désapprouvé presentModalViewController causant toutes sortes de problèmes de rotation ... vous devez utiliser presentViewController: animé: achèvement et vérifier comment votre application gère les changements
pourquoi

15

J'ai le même problème. J'essaie de présenter le contrôleur de vue juste après avoir rejeté.

[self dismissModalViewControllerAnimated:YES];

Quand j'essaie de le faire sans animation, cela fonctionne parfaitement, donc le problème est que le contrôleur est toujours en vie. Je pense que la meilleure solution est d'utiliser dismissViewControllerAnimated:completion:pour iOS5


Il échoue si vous le rejetez, car au moment où vous souhaitez présenter à nouveau le contrôleur de vue modale, il est toujours modal à l'écran, en cours d'animation.
Pascal

2
Il est déprécié dans IOS 6.0
Sumit Kumar Saha

12

Dans mon cas, j'essayais de présenter le viewController (j'ai la référence du viewController dans le TabBarViewController) à partir de différents contrôleurs de vue et il plantait avec le message ci-dessus. Dans ce cas, pour éviter de présenter, vous pouvez utiliser

viewController.isBeingPresented

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

Pourrait aider quelqu'un.


il ne fonctionne que dans viewWillappperar mais quand je l'ai vérifié avant de présenter viewController qui est déjà présenté, il retourne toujours false.
guru

1
Ne travaille pas pour moi. Obtient toujours un plantage de l'application. (! viewController.presentingViewController) a résolu le problème.
Argus

3

J'ai eu le même problème, je le résous. Vous pouvez essayer ce code:

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

2

La même erreur de problème m'est arrivée lorsque j'ai essayé presentun contrôleur de vue enfant au lieu de son UINavigationViewControllerparent


0

Retirez simplement

[tabBarController presentModalViewController:viewController animated:YES];

et garde

[self dismissModalViewControllerAnimated:YES];

cela donne un avertissement obsolète ... alors qu'est-ce qu'une alternative à cela?
Kirtikumar A.

Ici, j'ai utilisé [blockSelf licenciementViewControllerAnimated: OUI complétion: nil];
Kirtikumar A.

0

À la place d'utiliser:

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

vous pouvez utiliser:

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

0

Dans mon cas, je présentais le rootViewControllerd'un UINavigationControllerquand j'étais censé présenter le UINavigationControllerlui - même.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.