Attempt to present ViewController whose view is not in the windows hierarchy

前端 未结 6 1468
一整个雨季
一整个雨季 2020-12-14 13:34

I meet a strange problem: I made 2 view controllers for wich I can switch the view with code:

var currentViewController:UIViewController=UIApplication.shared         


        
相关标签:
6条回答
  • 2020-12-14 14:04

    Use like this

    let vc = self.view?.window?.rootViewController
    func showController()
    {
        let ViewControllernew1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController2")
    
        vc.present(ViewControllernew1, animated: true, completion: nil)
    }
    

    Maybe the issue is with the currentViewController.

    0 讨论(0)
  • 2020-12-14 14:08

    Calling function in viewDidAppear helps in my case. Solution for Swift 3:

    In your Main Controller:

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        showTutorialModally()
    }
    
    func showTutorialModally() {
        let tutorialViewController = TutorialViewController()
        tutorialViewController.modalPresentationStyle = .overCurrentContext
        present(tutorialViewController, animated: true, completion: nil)
    }
    

    In your Tutorial Controller:

    view.backgroundColor = UIColor.clear
    view.isOpaque = false
    
    0 讨论(0)
  • 2020-12-14 14:08

    Use the extension below to retrieve the next available controller in the stack.

    Swift 3

    extension UIResponder {
        func next<T: UIResponder>(_ type: T.Type) -> T? {
            return next as? T ?? next?.next(type)
        }
    }
    

    Swift 2.3

    extension UIResponder {
        func nextResponder<T: UIResponder>(_ type: T.Type) -> T? {
            return nextResponder() as? T ?? nextResponder()?.nextResponder(type)
        }
    }
    

    Inside your SKScene, view?.next(UIViewController.self) gives you the next available UIViewController in the hierarchy.

    Add this extension to a group in your project called Categories, if this group does not exist already create it, then create a new file called UIResponder+NextOfType.swift and paste the extension.

    0 讨论(0)
  • 2020-12-14 14:10

    Xcode error significance for roughly: this view is not in the Window of the view hierarchy.

    What I don't think the above answer questions, but maybe you might have wondered why this would happen.

    But I find that you are the reasons for this problem is likely to be in the ViewController life cycle at ViewDidLoading switch view Code execution inside.

    Reason is probably that, when the ViewController implementation allco init during initialization, it will be executed asynchronously viewWillLoad - > viewDidLoad... -- -- -- -- > viewDidApper. Then may be in code execution to the viewDidLoad. The ViewController may not assign values to the Window. The rootViewController. So we directly use [self presentViewController:] will appear this error.

    It is recommended that you move the code of the switch to ViewDidApper.

    I hope it will help you.

    0 讨论(0)
  • 2020-12-14 14:15
    1. Probably your rootViewController is not the current ViewController. Either you presented or pushed a new UIViewController on top of it.

    2. The viewController's view is not in the window's view hierarchy at the point that it has been loaded (when the viewDidLoad message is sent), but it is in the window hierarchy after it has been presented (when the viewDidAppear: message is sent). if you calling showController method from viewDidLoad just call it from viewDidAppear method

    Do something like:

     let vc: UIViewController = (self.storyboard?.instantiateViewControllerWithIdentifier("viewController2"))!
     self.presentViewController(vc, animated: true, completion: nil)
    

     // OR
     self.navigationController?.pushViewController(vc, animated: true)
    
    0 讨论(0)
  • 2020-12-14 14:17

    Issue

    Current viewController is not the rootViewController from UIApplication. So you should find the current viewController which is visible and then present it from there.

    Solution

    Simply find the topViewController on your UIApplication Stack, and from there present your controller.

    let newViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "viewController2")
    UIApplication.topViewController()?.present(newViewController, animated: true, completion: nil)
    

    This extension of UIApplication comes in handy for your case

    extension UIApplication {
        class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
            if let nav = base as? UINavigationController {
                return topViewController(base: nav.visibleViewController)
            }
            if let tab = base as? UITabBarController {
                if let selected = tab.selectedViewController {
                    return topViewController(base: selected)
                }
            }
            if let presented = base?.presentedViewController {
                return topViewController(base: presented)
            }
            return base
        }
    }
    

    References: Gist

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