首页 文章

警告:尝试在视图不在窗口层次结构中显示* on * - swift

提问于
浏览
74

如果数据模型中有任何已保存的数据,我正在尝试显示 ViewController . 但是我收到以下错误:

警告:尝试显示其视图不在窗口层次结构中的* on *

相关代码:

override func viewDidLoad() {
    super.viewDidLoad()
    loginButton.backgroundColor = UIColor.orangeColor()

    var request = NSFetchRequest(entityName: "UserData")
    request.returnsObjectsAsFaults = false

    var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
    var context:NSManagedObjectContext = appDel.managedObjectContext!

    var results:NSArray = context.executeFetchRequest(request, error: nil)!

    if(results.count <= 0){
        print("Inga resultat")
    } else {
        print("SWITCH VIEW PLOX")
        let internVC = self.storyboard?.instantiateViewControllerWithIdentifier("internVC") as internViewController
        self.presentViewController(internVC, animated: true, completion: nil)
    }
}

我尝试过使用谷歌找到的不同解决方案但没有成功 .

12 回答

  • 32

    在目标c:当在mpmovieplayer上呈现viewcontroller时,这解决了我的问题

    - (UIViewController*) topMostController
    {
        UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
    
        while (topController.presentedViewController) {
            topController = topController.presentedViewController;
        }
    
        return topController;
    }
    
  • 0

    此时,在代码中,视图控制器的视图仅已创建,但未添加到任何视图层次结构中 . 如果你想尽快从那个视图控制器出现,你应该在 viewDidAppear 中做到最安全 .

  • 0

    斯威夫特3

    我有这个不断出现作为一个新手,并发现当前加载模态视图,可以被解雇,但切换到根控制器是最好的,如果你不需要显示模态 .

    我正在使用它

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let vc  = storyboard?.instantiateViewController(withIdentifier: "MainAppStoryboard") as! TabbarController
    present(vc, animated: false, completion: nil)
    

    使用它来代替我的tabController:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let view = storyboard.instantiateViewController(withIdentifier: "MainAppStoryboard") as UIViewController
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    //show window
    appDelegate.window?.rootViewController = view
    

    如果您需要在多个故事板屏幕之间切换,只需调整到视图控制器即可 .

  • 2

    你只需要执行一个延迟选择器 - (0秒工作) .

    override func viewDidLoad() {
        super.viewDidLoad()
        perform(#selector(presentExampleController), with: nil, afterDelay: 0)
    }
    
    @objc private func presentExampleController() {
        let exampleStoryboard = UIStoryboard(named: "example", bundle: nil)
        let exampleVC = storyboard.instantiateViewController(withIdentifier: "ExampleVC") as! ExampleVC
        present(exampleVC, animated: true) 
    }
    
  • 28

    斯威夫特3 .

    调用此函数以获取最顶层的视图控制器,然后使该视图控制器存在 .

    func topMostController() -> UIViewController {
        var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
            while (topController.presentedViewController != nil) {
                topController = topController.presentedViewController!
            }
            return topController
        }
    

    用法:

    let topVC = topMostController()
    let vcToPresent = self.storyboard!.instantiateViewController(withIdentifier: "YourVCStoryboardID") as! YourViewController
    topVC.present(vcToPresent, animated: true, completion: nil)
    
  • 1

    对于SWIFT

    func topMostController() -> UIViewController {
        var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
        while (topController.presentedViewController != nil) {
            topController = topController.presentedViewController!
        }
        return topController
    }
    
  • 3

    斯威夫特4

    func topMostController() -> UIViewController {
        var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
        while (topController.presentedViewController != nil) {
            topController = topController.presentedViewController!
        }
        return topController
    }
    
  • 1

    对于swift 3.0及以上版本

    public static func getTopViewController() -> UIViewController?{
    if var topController = UIApplication.shared.keyWindow?.rootViewController
    {
      while (topController.presentedViewController != nil)
      {
        topController = topController.presentedViewController!
      }
      return topController
    }
    return nil}
    
  • 10
    let storyboard = UIStoryboard(name: "test", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: "teststoryboard") as UIViewController
    UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
    

    这似乎有助于确保它是最顶级的观点 .

    我收到了一个错误

    警告:尝试在myapp.testController上显示myapp.testController:0x7fdd01703990:0x7fdd01703690,其视图不在窗口层次结构中!

    希望这有助于其他人迅速3

  • 13

    我试过这么多approches!唯一有用的是:

    if var topController = UIApplication.shared.keyWindow?.rootViewController
    {
      while (topController.presentedViewController != nil)
      {
        topController = topController.presentedViewController!
      }
    }
    
  • 110

    当你有 UINavigationControllerUITabBarController 时,topViewController的所有实现都不是完全支持的情况,对于那两个你需要稍微不同的处理:

    对于 UITabBarControllerUINavigationController ,您需要一个不同的实现 .

    这是我用来获取topMostViewController的代码:

    protocol TopUIViewController {
        func topUIViewController() -> UIViewController?
    }
    
    extension UIWindow : TopUIViewController {
        func topUIViewController() -> UIViewController? {
            if let rootViewController = self.rootViewController {
                return self.recursiveTopUIViewController(from: rootViewController)
            }
    
            return nil
        }
    
        private func recursiveTopUIViewController(from: UIViewController?) -> UIViewController? {
            if let topVC = from?.topUIViewController() { return recursiveTopUIViewController(from: topVC) ?? from }
            return from
        }
    }
    
    extension UIViewController : TopUIViewController {
        @objc open func topUIViewController() -> UIViewController? {
            return self.presentedViewController
        }
    }
    
    extension UINavigationController {
        override open func topUIViewController() -> UIViewController? {
            return self.visibleViewController
        }
    }
    
    extension UITabBarController {
        override open func topUIViewController() -> UIViewController? {
            return self.selectedViewController ?? presentedViewController
        }
    }
    
  • 12

    可以使用,而不是找到顶视图控制器

    viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext
    

    其中viewController是你想要呈现的控制器当像TabBar,NavBar这样的层次结构中存在不同类型的视图时这很有用,尽管其他视图似乎是正确的但更多的是hackish

    其他演示风格可在apple doc找到

相关问题