20
votes

I'm using xcode 5.1.1 with storyboard. I have a button on main menu and it pops to another view controller with this code

VC *secondVC = [[VC alloc] init];
[self presentViewController:secondVC animated:YES completion: nil];

And there I have back button with this code

[self dismissViewControllerAnimated:YES completion: nil];

And when I pop to secondVC xcode gives me is error:

Presenting view controllers on detached view controllers is discourage <UINavigationController: 0x8c94510>.

I'm also having problem with rotation, it doesn't work properly.

11

11 Answers

18
votes

This warning will come up if if you are trying to push, present or pop view controllers in viewWillAppear. I don't know what is in your code so it's tough to identify your problem but try using this if you are trying to show new views in viewWillAppear.

[self performSelector:@selector(yourMethod)
               withObject:nil afterDelay:0.0];
11
votes

Present the controller from viewDidAppear: instead.

11
votes

I ran into a similar situation while attempting to present an UIAlertController from viewWillAppear. Since performSelector does not exist in Swift, I wrapped my call this way:

dispatch_async(dispatch_get_main_queue()), {
    presentYourVCHere;
});
8
votes

Try pushing from rootVC:

[self.view.window.rootViewController.navigationController pushViewController:YOUR_VIEW_CONTROLER animated:YES];
3
votes

try calling the same action in viewDidAppear. this warning is due to when we present any view in viewDidLoad or viewWillAppear method.

so do this in override func viewDidAppear(animated: Bool) { ... }

2
votes

I was trying to present the UIViewController from a splitViewController.

This is what solved my issue:

self.view.window.rootViewController.present(yourViewController, animated: true, completion: nil)
1
votes

If anyone wonder how you could do this using swift (even can be used in Objective C), following code help me to overcome the above issue. Use this code inside the viewDidLoad()

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), { () -> Void in
         //this place to call segue or manually load the view. 
})
1
votes

in case this error happens from popup view controller you need to call the code for show the alert controller directly from parent view using delegation. For example in your parent view controller:

-(void) showAlertError: (YourClass *) whateverParameter {
    dispatch_async(dispatch_get_main_queue(), ^{
        UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Your Title"
                                                                       message:@"Your message"
                                                                preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                              handler:^(UIAlertAction * action) {}];
        [alert addAction:defaultAction];
        [self presentViewController:alert animated:YES completion:nil];
    });
}

And in your child view:

- (IBAction)btnDone:(id)sender{
    [self.delegate showAlertError:self];
}
1
votes

None of the answers helped me. And here the code which I used to resolve the issue.

let topViewController = (self.navigationController?.viewControllers.last)! as UIViewController
topViewController.presentViewController(secondView, animated: true, completion: nil)

Hope this will help someone :)

1
votes

I was getting the same error when presenting a UIAlertController from a UIViewController (vc2) nested inside another UIViewController (vc1)

I solved it like so:

[vc1 addChildViewController:vc2]

After doing that I could present UIAlertController from vc2 without any error messages.

0
votes