【问题标题】:Attempt to present UIViewController on UIViewController whose view is not in the window hierarchy尝试在其视图不在窗口层次结构中的 UIViewController 上呈现 UIViewController
【发布时间】:2012-08-05 11:11:51
【问题描述】:

刚开始使用 Xcode 4.5,我在控制台中收到此错误:

警告:尝试在 上显示 ,其视图不在窗口层次结构中!

视图仍在呈现,应用程序中的所有内容都运行良好。这是 iOS 6 中的新功能吗?

这是我用来在视图之间切换的代码:

UIStoryboard *storyboard = self.storyboard;
finishViewController *finished = 
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];

【问题讨论】:

  • 我遇到了完全相同的问题,除了尝试在导航控制器上调用 presentViewController:animated:completion。您是否在应用委托中执行此操作?
  • 不,我是从一个视图控制器到另一个视图控制器。你找到解决办法了吗?
  • 在使用 Xcode 4.5 之前一直有效的部分代码存在同样的问题,我正在展示一个 UINavigationController,但这在之前一直有效。
  • 我有同样的问题,没有解决。从应用程序委托执行此操作,并且 rootviewcontroller 调用“presentViewController”作为 UITabBarController。
  • 另外,如果在调用makeKeyAndVisible之前调用了这个方法,那么在之后移动它

标签: ios cocoa-touch ios6 views hierarchy


【解决方案1】:

该消息显示为警告,有时代码拒绝工作。 (!需要引用:较新的 SDK 可能有严格的规则)。

我遇到它的原因不止一个,主要是复杂的视图控制器场景。这是一个例子。

Scenario: MainViewController (responsible to load: ViewControllerA & ViewControllerB)

MainViewController 呈现ViewControllerA 并且在不关闭ViewControllerA 的情况下尝试从MainViewController 呈现viewControllerB(使用委托方法)。

在这种情况下,您必须确保 ViewControllerA 被解除,然后 ViewControllerB 被调用。

因为在呈现 ViewControllerA 之后(ViewControllerA 负责显示视图和视图控制器,当 MainViewController 尝试加载另一个视图控制器时,它拒绝工作并抛出警告)。

【讨论】:

    【解决方案2】:

    你可以调用你的 segues 或在这个块内展示、推送代码:

    override func viewDidLoad() {
        super.viewDidLoad()
        OperationQueue.main.addOperation {
            // push or present the page inside this block
        }
    }
    

    【讨论】:

      【解决方案3】:

      斯威夫特 5

      我在viewDidLayoutSubviews 中调用出现在viewDidAppear 中出现会导致视图控制器在加载模式之前瞬间显示,这看起来像一个丑陋的故障

      确保检查窗口是否存在并只执行一次代码

      var alreadyPresentedVCOnDisplay = false
      
      override func viewDidLayoutSubviews() {
              
          super.viewDidLayoutSubviews()
          
          // we call present in viewDidLayoutSubviews as
          // presenting in viewDidAppear causes a split second showing 
          // of the view controller before the modal is loaded
          
          guard let _ = view?.window else {
              // window must be assigned
              return
          }
          
          if !alreadyPresentedVCOnDisplay {
              alreadyPresentedVCOnDisplay = true
              present(...)
          }
          
      }
      

      【讨论】:

        【解决方案4】:

        Swift 5 - 后台线程

        如果在后台线程上执行警报控制器,则可能会出现“尝试呈现...其视图不在窗口层次结构中”的错误。

        所以这个:

        present(alert, animated: true, completion: nil)
            
        

        已修复:

        DispatchQueue.main.async { [weak self] in
            self?.present(alert, animated: true, completion: nil)
        }
        

        【讨论】:

        • 这是我的问题。谢谢!
        【解决方案5】:

        这发生在我试图呈现到我的 navigationController 时,它的视图还没有呈现到视图层次结构上。我解决这个问题的方法是听NavigationControllerDelegate's didShow method。一旦调用了 didShow 方法,我就知道我可以在我的 navigationController 上呈现。

        注意:使用dispatchQueueAsync.await(.now()) { //present } 确实有效,但如果视图需要很长时间才能显示到视图层次结构上,它会很麻烦并且容易出现错误。

        【讨论】:

          猜你喜欢
          • 2016-03-26
          • 2016-01-06
          • 2015-04-27
          • 2017-04-01
          • 1970-01-01
          相关资源
          最近更新 更多