Warning :-Presenting view controllers on detached view controllers is discouraged

IosIphoneCocoa TouchIos7Warnings

Ios Problem Overview


In my app, I am using a navigation controller. Later on in some view I am using presentViewController for showing a zoomed image. Also I am not using a Storyboard or nib.

I am getting this error in iOS 7 only. It works fine in iOS 6 and earlier:

> Presenting view controllers on detached view controllers is > discouraged

Ios Solutions


Solution 1 - Ios

To avoid getting the warning in a push navigation, you can directly use :

[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];

And then in your modal view controller, when everything is finished, you can just call :

[self dismissViewControllerAnimated:YES completion:nil];

Solution 2 - Ios

Wait for viewDidAppear():

This error can also arise if you are trying to present view controller before view actually did appear, for example presenting view in viewWillAppear() or earlier. Try to present another view after viewDidAppear() or inside of it.

Solution 3 - Ios

The reason of this warning is i was presenting a view controller over a small view that is not full size view. Given below is the image of my project. where on click on four option above. User navigate to different childviewcontroller's view.(it works like tabViewcontroller). But the childviewcontroller contains view of small size. So if we present a view from childviewcontroller it gives this warning.

master detail view

And to avoid this, you can present a view on childviewcontroller's parent

  [self.parentViewController presentViewController:viewController animated:YES completion:nil];

Solution 4 - Ios

In my case, I've a sampleViewController's view added as a subview, then tries to present a popover from the view of sampleViewController (here self instead a UIViewController instance):

[self.view addSubview:sampleViewController.view];

The right way should be below:

// 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];

B.t.w., this also works for the case that present a popover form a tableview cell, you just need to make sure the tableview controller has been added as child view controller as well.

Solution 5 - Ios

Swift 3

For anyone stumbling on this, here is the swift answer.

self.parent?.present(viewController, animated: true, completion: nil)

Solution 6 - Ios

I think that the problem is that you do not have a proper view controller hierarchy. Set the rootviewcontroller of the app and then show new views by pushing or presenting new view controllers on them. Let each view controller manage their views. Only container view controllers, like the tabbarviewcontroller, should ever add other view controllers views to their own views. Read the view controllers programming guide to learn more on how to use view controllers properly. https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/

Solution 7 - Ios

I have almost the same problem. The reason was that I tried to present "some" controller on another and after animation was completed I was setting presented controller as root. After this operation all further controllers presenting bring me to the warning: "Presenting view controllers on detached view controllers is discouraged". And I solve this warning just settings "some" controller as root without any presentation at the begin.

Removed:

[[self rootController] presentViewController:controller animated:YES completion:^{

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

Just make as root without any presentation:

 [[self window] setRootViewController:controller];

Solution 8 - Ios

One of the solution to this is if you have childviewcontroller So you simply presentviewcontroller on its parent by given

[self.parentViewController presentViewController:viewController animated:YES completion:nil];

And for dismiss use the same dismissview controller.

[self dismissViewControllerAnimated:YES completion:nil];

This is perfect solution works for me.

Solution 9 - Ios

Use [self.navigationController presentViewController:xxx animated:YES completion:nil] in iOS 8.

Solution 10 - Ios

Try this code

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];

[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];

Solution 11 - Ios

In Swift 4.1 and Xcode 9.4.1

The solution is

DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

If write like this i'm getting same error

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) 

I'm getting same error

Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.

Complete solution is

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)
})

Solution 12 - Ios

Yes, I also faced the same warning message while displaying an Alert controller which was in another view. Later on I avoided this by presenting the alert controller from the parent view controller as below:

[self.parentViewController presentViewController:alertController animated:YES completion:nil];

Solution 13 - Ios

Try presenting on TabBarController if it is a TabBarController based app .

[self.tabBarController presentViewController:viewController animated:YES completion:nil];

Reason could be self is child of TabBarController and you are trying to present from a ChildViewController.

Solution 14 - Ios

you need to add the view controller that will present the new controller as a child of the parent view controller.

Let's say you have yourMainViewController, then you add a new controller called controllerA, and then you want to present a new controller called controllerB from controllerA

you have to write something like this:

[self addChildViewController:controllerA]; //self is yourMainViewController
[self.view addsubView:controllerA.view]; 

and within controllerA you can present the new controller without warnings

[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA

Solution 15 - Ios

I reached on this thread where I have a Custom Navigation Bar and I was calling an AlertViewController through it.

I had to add it as a child to my main view controller. Then I could call present it without any warning.

You should add your Zoomed Image View Controller as a child of the main ViewController.

(e.g)

[self addChildViewController:ZoomedImageViewController];

Then you'd be able to call your ZoomedImageViewController

[self presentViewController:ZoomedImageViewController];



Solution 16 - Ios

Make sure you have a root view controller to start with. You can set it in didFinishLaunchingWithOptions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [window setRootViewController:viewController];
}

Solution 17 - Ios

Lots of reasons for this warning. Mine is because I have a segue connected from a ViewController to another that will be presented modally. But, the ViewController I am presenting from is being dynamically generated by a PageViewController. Which is why it is detached in the Storyboard. My app isn't going to crash because of it; but I would like to silence the warning.

Solution 18 - Ios

It depends if you want to show your alert or something similar in anywhere of kind UIViewController.

You can use this code example:

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];

Solution 19 - Ios

Many answers are right.

  • Check your presentingViewController have parentViewController or not.
  • If no, add it to somewhere it should be added
  • else, check it's parentViewController has parentViewController recursively until every viewController has parent

This issue happened to me when my co-worker add a AViewController to BViewController. Somehow, he just add the AViewController's view to BViewController's view.

Fixed by add bViewController.addChild(aViewController)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGagan JoshiView Question on Stackoverflow
Solution 1 - IoscdescoursView Answer on Stackoverflow
Solution 2 - IosAzaxisView Answer on Stackoverflow
Solution 3 - IosGagan JoshiView Answer on Stackoverflow
Solution 4 - IosKjulyView Answer on Stackoverflow
Solution 5 - IosJeremieView Answer on Stackoverflow
Solution 6 - IosDaniel YtterbrinkView Answer on Stackoverflow
Solution 7 - IosaveremView Answer on Stackoverflow
Solution 8 - IosGagan JoshiView Answer on Stackoverflow
Solution 9 - IosTao FangView Answer on Stackoverflow
Solution 10 - IosVladView Answer on Stackoverflow
Solution 11 - IosNareshView Answer on Stackoverflow
Solution 12 - IosSivasagar PalakurthyView Answer on Stackoverflow
Solution 13 - IosWarif Akhand RishiView Answer on Stackoverflow
Solution 14 - IosChuy47View Answer on Stackoverflow
Solution 15 - IosNaveed AbbasView Answer on Stackoverflow
Solution 16 - IossamwizeView Answer on Stackoverflow
Solution 17 - IosLee ProbertView Answer on Stackoverflow
Solution 18 - IosFabioView Answer on Stackoverflow
Solution 19 - IosJerome LiView Answer on Stackoverflow