刚开始使用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];

当前回答

我的问题是,在我调用窗口上的makeKeyAndVisible()之前,我在UIApplicationDelegate的didFinishLaunchingWithOptions方法中执行segue。

其他回答

要将任何子视图显示到主视图,请使用以下代码

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController presentViewController:composeViewController animated:YES completion:nil];

对于从主视图中解散任何子视图,请使用以下代码

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

while (yourCurrentViewController.presentedViewController) 
{
   yourCurrentViewController = yourCurrentViewController.presentedViewController;
}

[yourCurrentViewController dismissViewControllerAnimated:YES completion:nil];

遗憾的是,这个公认的解决方案并不适用于我的案例。我试图在从另一个视图控制器unwind后导航到一个新的视图控制器。

我找到了一个解决方案,使用一个标志来指示哪个unwind segue被调用。

@IBAction func unwindFromAuthenticationWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToMainTabBar = true
}

@IBAction func unwindFromForgetPasswordWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToLogin = true
}

然后用present(_ viewcontrollertoppresent: UIViewController)来呈现想要的VC

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if self.shouldSegueToMainTabBar {
        let mainTabBarController = storyboard.instantiateViewController(withIdentifier: "mainTabBarVC") as! MainTabBarController
        self.present(mainTabBarController, animated: true)
        self.shouldSegueToMainTabBar = false
    }
    if self.shouldSegueToLogin {
        let loginController = storyboard.instantiateViewController(withIdentifier: "loginVC") as! LogInViewController
        self.present(loginController, animated: true)
        self.shouldSegueToLogin = false
    }
}

基本上,上面的代码将让我从login/SignUp VC捕获unwind并导航到仪表板,或者从forget password VC捕获unwind操作并导航到登录页面。

In case it helps anyone, my issue was extremely silly. Totally my fault of course. A notification was triggering a method that was calling the modal. But I wasn't removing the notification correctly, so at some point, I would have more than one notification, so the modal would get called multiple times. Of course, after you call the modal once, the viewcontroller that calls it it's not longer in the view hierarchy, that's why we see this issue. My situation caused a bunch of other issue too, as you would expect.

总之,无论你做什么,都要确保模态不会被调用超过一次。

我在更新Xcode后发现了这个bug,我相信是Swift 5。当我在展开视图控制器后通过编程方式直接启动segue时,问题就发生了。

解决方案到来的同时修复了一个相关的错误,即用户现在可以通过向下滑动页面来unwind segue。这打破了我程序的逻辑。

通过将所有视图控制器上的演示模式从自动更改为全屏,可以解决这个问题。

你可以在界面构建器的属性面板中完成。或者查看这个答案,了解如何以编程方式完成。

它工作得很好,试试这个。链接

UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
[top presentViewController:secondView animated:YES completion: nil];