刚开始使用Xcode 4.5,我在控制台得到了这个错误:

警告:试图在< ViewController: 0x1ec3e000>上显示< finishViewController: 0x1e56e0a0 >,其视图不在窗口层次结构中!

视图仍在显示,应用程序中的一切都在正常工作。这是iOS 6的新功能吗?

这是我用来在视图之间更改的代码:

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

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

当前回答

斯威夫特5

我在viewDidLayoutSubviews中调用present,因为在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(...)
    }
    
}

其他回答

我在Swift 4.2上也有类似的问题,但我的观点没有从视图周期中呈现出来。我发现我有多个segue要同时呈现。所以我使用dispatchAsyncAfter。

func updateView() {

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in

// for programmatically presenting view controller 
// present(viewController, animated: true, completion: nil)

//For Story board segue. you will also have to setup prepare segue for this to work. 
 self?.performSegue(withIdentifier: "Identifier", sender: nil)
  }
}

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

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

你从哪里调用这个方法?我有一个问题,我试图在viewDidLoad方法中呈现一个模态视图控制器。我的解决方案是将这个调用移动到viewDidAppear:方法。

我的假设是,视图控制器的视图在它被加载时(当viewDidLoad消息被发送时)不在窗口的视图层次结构中,但在它被呈现后(当viewDidAppear:消息被发送时)它在窗口层次结构中。


谨慎

如果你确实调用了viewDidAppear:中的presentViewController:animated:completion:,你可能会遇到这样一个问题,即每当视图控制器的视图出现时,模态视图控制器总是被呈现(这是有意义的!),因此模态视图控制器被呈现永远不会消失……

也许这不是呈现模态视图控制器的最佳位置,或者可能需要保留一些额外的状态让呈现的视图控制器决定是否应该立即呈现模态视图控制器。

这适用于呈现任何视图控制器,如果你有可用的导航控制器。 self.navigationController ?。present(MyViewController, animated: true, completion: nil) 此外,我可以能够呈现警报和邮件控制器也。

用Swift 3…

另一个可能的原因,发生在我身上,是从一个tableViewCell segue到Storyboard上的另一个ViewController。当单元格被单击时,我还使用override func prepare(for segue: UIStoryboardSegue, sender: Any?){}。

我通过创建一个从ViewController到ViewController的segue来解决这个问题。