Dans mon application, j'utilise un contrôleur de navigation. Plus tard, dans une vue que j'utilise presentViewController
pour afficher une image agrandie. De plus, je n'utilise pas de Storyboard ou de plume.
Je reçois cette erreur dans iOS 7 uniquement. Cela fonctionne bien dans iOS 6 et les versions antérieures:
La présentation de contrôleurs de vue sur des contrôleurs de vue détachés est déconseillée
Réponses:
Pour éviter de recevoir l'avertissement dans une navigation push, vous pouvez utiliser directement:
[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];
Et puis dans votre contrôleur de vue modale, lorsque tout est terminé, vous pouvez simplement appeler:
[self dismissViewControllerAnimated:YES completion:nil];
la source
self.navigationController
fait pour moi.Attendre
viewDidAppear()
:Cette erreur peut également survenir si vous essayez de présenter le contrôleur de vue avant que la vue n'apparaisse réellement, par exemple en présentant une vue dans
viewWillAppear()
ou avant. Essayez de présenter une autre vue aprèsviewDidAppear()
ou à l'intérieur.la source
viewDidLoad()
, people! J'ai fait cette erreur tant de fois ...La raison de cet avertissement est que je présentais un contrôleur de vue sur une petite vue qui n'est pas une vue en taille réelle. Ci-dessous, l'image de mon projet. où cliquez sur quatre options ci-dessus. L'utilisateur accède à une vue différente de childviewcontroller (cela fonctionne comme tabViewcontroller). Mais le childviewcontroller contient une vue de petite taille. Donc, si nous présentons une vue de childviewcontroller, cela donne cet avertissement.
Et pour éviter cela, vous pouvez présenter une vue sur le parent de childviewcontroller
[self.parentViewController presentViewController:viewController animated:YES completion:nil];
la source
Dans mon cas, j'ai
sampleViewController
ajouté une vue de sous en tant que sous-vue, puis essaie de présenter un popover à partir de la vue desampleViewController
(ici à laself
place uneUIViewController
instance):[self.view addSubview:sampleViewController.view];
La bonne manière devrait être ci-dessous:
// make sure the vc has been added as a child view controller as well [self addChildViewController:sampleViewController]; [self.view addSubview:sampleViewController.view]; [sampleViewController didMoveToParentViewController:self];
Btw, cela fonctionne également pour le cas qui présente un popover d'une cellule tableview, il vous suffit de vous assurer que le contrôleur tableview a également été ajouté en tant que contrôleur de vue enfant.
la source
[self addChildViewController:sampleViewController];
, maintenant j'ai ajouté ceci, merciJe pense que le problème est que vous n'avez pas une hiérarchie de contrôleur de vue appropriée. Définissez le rootviewcontroller de l'application, puis affichez de nouvelles vues en poussant ou en présentant de nouveaux contrôleurs de vue dessus. Laissez chaque contrôleur de vue gérer ses vues. Seuls les contrôleurs de vue de conteneur, comme le tabbarviewcontroller, devraient ajouter d'autres vues de contrôleurs de vue à leurs propres vues. Lisez le guide de programmation des contrôleurs de vue pour en savoir plus sur l'utilisation correcte des contrôleurs de vue. https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/
la source
Swift 3
Pour quiconque trébuche là-dessus, voici la réponse rapide.
self.parent?.present(viewController, animated: true, completion: nil)
la source
J'ai presque le même problème. La raison était que j'ai essayé de présenter "un" contrôleur sur un autre et une fois l'animation terminée, je définissais le contrôleur présenté en tant que root. Après cette opération, tous les autres contrôleurs qui se présentent m'amènent à l'avertissement: «La présentation de contrôleurs de vue sur des contrôleurs de vue détachés est déconseillée ". Et je résous cet avertissement juste en paramétrant "un" contrôleur en tant que root sans aucune présentation au début.
Supprimé:
[[self rootController] presentViewController:controller animated:YES completion:^{ [self window].rootViewController = controller; [[self window] makeKeyAndVisible];}];
Faites simplement en tant que root sans aucune présentation:
[[self window] setRootViewController:controller];
la source
Une des solutions à cela est si vous avez childviewcontroller Donc vous présentez simplementviewcontroller sur son parent en donnant
[self.parentViewController presentViewController:viewController animated:YES completion:nil];
Et pour ignorer, utilisez le même contrôleur de rejet.
[self dismissViewControllerAnimated:YES completion:nil];
C'est la solution parfaite qui fonctionne pour moi.
la source
Utiliser
[self.navigationController presentViewController:xxx animated:YES completion:nil]
sous iOS 8.la source
Essayez ce code
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>]; [self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];
la source
Essayez de présenter
TabBarController
s'il s'agit d'uneTabBarController
application basée.[self.tabBarController presentViewController:viewController animated:YES completion:nil];
La raison pourrait être un
self
enfant deTabBarController
et vous essayez de présenter à partir d'un fichierChildViewController
.la source
Dans Swift 4.1 et Xcode 9.4.1
La solution est
DispatchQueue.main.async(execute: { self.present(alert, animated: true) })
Si j'écris comme ça, j'obtiens la même erreur
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert) let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in }) alert.addAction(defaultAction) present(alert, animated: true, completion: nil)
Je reçois la même erreur
Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.
La solution complète est
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert) let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in }) alert.addAction(defaultAction) //Made Changes here DispatchQueue.main.async(execute: { self.present(alert, animated: true) })
la source
Oui, j'ai également rencontré le même message d'avertissement lors de l'affichage d'un contrôleur d'alerte qui était dans une autre vue. Plus tard, j'ai évité cela en présentant le contrôleur d'alerte du contrôleur de vue parent comme ci-dessous:
[self.parentViewController presentViewController:alertController animated:YES completion:nil];
la source
vous devez ajouter le contrôleur de vue qui présentera le nouveau contrôleur en tant qu'enfant du contrôleur de vue parent.
Disons que vous avez yourMainViewController, puis vous ajoutez un nouveau contrôleur appelé controllerA, et ensuite vous voulez présenter un nouveau contrôleur appelé controllerB de controllerA
vous devez écrire quelque chose comme ceci:
[self addChildViewController:controllerA]; //self is yourMainViewController [self.view addsubView:controllerA.view];
et dans controllerA vous pouvez présenter le nouveau contrôleur sans avertissement
[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA
la source
Assurez-vous que vous disposez d'un contrôleur de vue racine pour commencer. Vous pouvez l'installer
didFinishLaunchingWithOptions
.- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [window setRootViewController:viewController]; }
la source
Beaucoup de raisons pour cet avertissement. Le mien est parce que j'ai un segue connecté d'un ViewController à un autre qui sera présenté de manière modale. Mais, le ViewController que je présente est généré dynamiquement par un PageViewController. C'est pourquoi il est détaché dans le Storyboard. Mon application ne va pas planter à cause de cela; mais je voudrais faire taire l'avertissement.
la source
J'ai atteint sur ce fil où j'ai une barre de navigation personnalisée et j'appelais un AlertViewController à travers elle.
J'ai dû l'ajouter en tant qu'enfant à mon contrôleur de vue principal. Ensuite, je pourrais appeler présent sans aucun avertissement.
Vous devez ajouter votre en
Zoomed Image View Controller
tant qu'enfant du ViewController principal.(par exemple)
[self addChildViewController:ZoomedImageViewController];
Ensuite, vous pourrez appeler votre ZoomedImageViewController
[self presentViewController:ZoomedImageViewController];
la source
De nombreuses réponses sont justes.
Ce problème m'est arrivé lorsque mon collègue a ajouté un AViewController à BViewController. D'une manière ou d'une autre, il ajoute simplement la vue AViewController à la vue BViewController.
Corrigé par ajouter bViewController.addChild (aViewController)
la source
Cela dépend si vous voulez afficher votre alerte ou quelque chose de similaire dans n'importe quel endroit du genre UIViewController.
Vous pouvez utiliser cet exemple de code:
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Example" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil]; [alert addAction:cancelAction]; [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alert animated:true completion:nil];
la source
Attempt to present <UIAlertController: 0x7fc01a1eb600> on <ViewController: 0x7fc019821e00> whose view is not in the window hierarchy!