Attempt to present UIViewController on UIViewController whose view is not in the window hierarchy

后端 未结 30 3055
一整个雨季
一整个雨季 2020-11-21 23:39

Just started using Xcode 4.5 and I got this error in the console:

Warning: Attempt to present < finishViewController: 0x1e56e0a0 > on < ViewCont

相关标签:
30条回答
  • 2020-11-21 23:58

    This kind of warning can mean that You're trying to present new View Controller through Navigation Controller while this Navigation Controller is currently presenting another View Controller. To fix it You have to dismiss currently presented View Controller at first and on completion present the new one. Another cause of the warning can be trying to present View Controller on thread another than main.

    0 讨论(0)
  • 2020-11-21 23:58

    You can call your segues or present, push codes inside this block:

    override func viewDidLoad() {
        super.viewDidLoad()
        OperationQueue.main.addOperation {
            // push or present the page inside this block
        }
    }
    
    0 讨论(0)
  • 2020-11-21 23:59

    TL;DR You can only have 1 rootViewController and its the most recently presented one. So don't try having a viewcontroller present another viewcontroller when it's already presented one that hasn't been dismissed.

    After doing some of my own testing I've come to a conclusion.

    If you have a rootViewController that you want to present everything then you can run into this problem.

    Here is my rootController code (open is my shortcut for presenting a viewcontroller from the root).

    func open(controller:UIViewController)
    {
        if (Context.ROOTWINDOW.rootViewController == nil)
        {
            Context.ROOTWINDOW.rootViewController = ROOT_VIEW_CONTROLLER
            Context.ROOTWINDOW.makeKeyAndVisible()
        }
    
        ROOT_VIEW_CONTROLLER.presentViewController(controller, animated: true, completion: {})
    }
    

    If I call open twice in a row (regardless of time elapsed), this will work just fine on the first open, but NOT on the second open. The second open attempt will result in the error above.

    However if I close the most recently presented view then call open, it works just fine when I call open again (on another viewcontroller).

    func close(controller:UIViewController)
    {
        ROOT_VIEW_CONTROLLER.dismissViewControllerAnimated(true, completion: nil)
    }
    

    What I have concluded is that the rootViewController of only the MOST-RECENT-CALL is on the view Hierarchy (even if you didn't dismiss it or remove a view). I tried playing with all the loader calls (viewDidLoad, viewDidAppear, and doing delayed dispatch calls) and I have found that the only way I could get it to work is ONLY calling present from the top most view controller.

    0 讨论(0)
  • 2020-11-22 00:03

    I also encountered this problem when I tried to present a UIViewController in viewDidLoad. James Bedford's answer worked, but my app showed the background first for 1 or 2 seconds.

    After some research, I've found a way to solve this using the addChildViewController.

    - (void)viewDidLoad
    {
        ...
        [self.view addSubview: navigationViewController.view];
        [self addChildViewController: navigationViewController];
        ...
    }
    
    0 讨论(0)
  • 2020-11-22 00:03

    In my situation, I was not able to put mine in a class override. So, here is what I got:

    let viewController = self // I had viewController passed in as a function,
                              // but otherwise you can do this
    
    
    // Present the view controller
    let currentViewController = UIApplication.shared.keyWindow?.rootViewController
    currentViewController?.dismiss(animated: true, completion: nil)
    
    if viewController.presentedViewController == nil {
        currentViewController?.present(alert, animated: true, completion: nil)
    } else {
        viewController.present(alert, animated: true, completion: nil)
    }
    
    0 讨论(0)
  • 2020-11-22 00:03

    I had the same issue. The problem was, the performSegueWithIdentifier was triggered by a notification, as soon as I put the notification on the main thread the warning message was gone.

    0 讨论(0)
提交回复
热议问题