警告: 不建议在分离的视图控制器上显示视图控制器

在我的应用程序中,我使用的是导航控制器。后来在一些视图中,我使用 presentViewController来显示缩放的图像。 我也没有使用故事板或笔尖。

我只是在 iOS7中遇到了这个错误,它在 iOS6及更早的版本中运行良好:

在分离的视图控制器上显示视图控制器是 气馁

146439 次浏览

我认为问题在于您没有合适的视图控制器层次结构。设置应用程序的 rootviewcontroller,然后通过推送或显示新的视图控制器来显示新的视图。让每个视图控制器管理它们的视图。只有容器视图控制器(如 tabbarviewcontroller)应该将其他视图控制器视图添加到自己的视图中。阅读视图控制器编程指南,了解有关如何正确使用视图控制器的更多信息。https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/

为了避免在推送导航中出现警告,您可以直接使用:

[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];

然后在模态视图控制器中,当所有操作都完成时,您可以调用:

[self dismissViewControllerAnimated:YES completion:nil];

确保您有一个根视图控制器来开始。您可以在 didFinishLaunchingWithOptions中设置它。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window setRootViewController:viewController];
}

我也有同样的问题。原因是我试图呈现“一些”控制器在另一个和动画完成后,我设置呈现控制器为根。在这个操作之后,所有进一步提出的控制器带给我的警告: “ 不鼓励在分离的视图控制器上显示视图控制器”。我解决这个警告只是设置“一些”控制器作为根没有任何演示在开始。

删除:

[[self rootController] presentViewController:controller animated:YES completion:^{


[self window].rootViewController = controller;


[[self window] makeKeyAndVisible];}];

只要作为 root 用户使用,不需要任何演示:

 [[self window] setRootViewController:controller];

这个警告的原因是我在一个不是全尺寸视图的小视图上展示了一个视图控制器。下面是我的项目的图片。点击上面的四个选项。用户导航到不同的儿童视图控制器视图。(它的工作方式类似于 tabViewcontroller)。但是儿童视图控制器包含小尺寸的视图。因此,如果我们呈现一个来自 child viewcontroller 的视图,它会给出这个警告。

master detail view

为了避免这种情况,您可以在 child viewcontroller 的父节点上显示一个视图

  [self.parentViewController presentViewController:viewController animated:YES completion:nil];

解决这个问题的方法之一是,如果你有 child viewcontroller,那么你只需要在它的父节点上给出

[self.parentViewController presentViewController:viewController animated:YES completion:nil];

对于解雇,使用相同的解雇视图控制器。

[self dismissViewControllerAnimated:YES completion:nil];

这是完美的解决方案,对我有效。

在 iOS8中使用 [self.navigationController presentViewController:xxx animated:YES completion:nil]

在我的例子中,我添加了一个 sampleViewController视图作为子视图,然后尝试从 sampleViewController视图显示一个弹出窗口(这里是 self而不是 UIViewController实例) :

[self.view addSubview:sampleViewController.view];

正确的方法应该是:

// make sure the vc has been added as a child view controller as well
[self addChildViewController:sampleViewController];
[self.view addSubview:sampleViewController.view];
[sampleViewController didMoveToParentViewController:self];

这也适用于在表单元格中显示弹出窗口的情况,您只需要确保表单元格控制器也被添加为子视图控制器。

是的,当我在另一个视图中显示 Alert 控制器时,我也遇到了同样的警告消息。后来,我通过在父视图控制器中显示警报控制器来避免这种情况,如下所示:

[self.parentViewController presentViewController:alertController animated:YES completion:nil];

等待 viewDidAppear():

如果试图在视图实际出现之前呈现视图控制器,也可能出现此错误,例如在 viewWillAppear()或更早版本中呈现视图。 尝试在 viewDidAppear()之后显示另一个视图或在其中显示另一个视图。

您需要添加将新控制器作为父视图控制器的子控制器呈现的视图控制器。

假设您有 MainViewController,然后添加一个名为 controller A 的新控制器,然后希望从 controller A 中显示一个名为 controller B 的新控制器

你必须这样写:

[self addChildViewController:controllerA]; //self is yourMainViewController
[self.view addsubView:controllerA.view];

在 controller A 中,您可以在没有警告的情况下显示新的控制器

[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA

试试这个代码

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];


[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];

这个警告有很多理由。我的是因为我有一个连接从一个视图控制器到另一个将提出模态。但是,我正在展示的 ViewController 是由 PageViewController 动态生成的。这就是为什么它被分离在故事板中。我的应用程序不会因为它而崩溃,但是我想让这个警告消失。

Swift 3

对于任何碰巧发现这个问题的人,这里有一个快速的答案。

self.parent?.present(viewController, animated: true, completion: nil)

如果它是一个基于 TabBarController的应用程序,请尝试在 TabBarController上演示。

[self.tabBarController presentViewController:viewController animated:YES completion:nil];

原因可能是 selfTabBarController的孩子,你正试图从 ChildViewController呈现。

这取决于您是否希望在任何类型的 UIViewController 中显示警报或类似的内容。

您可以使用下面的代码示例:

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Example" preferredStyle:UIAlertControllerStyleAlert];


UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil];


[alert addAction:cancelAction];




[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alert animated:true completion:nil];

在 Swift 4.1和 Xcode 9.4.1中

解决办法就是

DispatchQueue.main.async(execute: {
self.present(alert, animated: true)
})

如果像这样写,我会得到同样的错误

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
})
alert.addAction(defaultAction)


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

我得到了同样的错误

Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.

完全的解决办法是

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
})
alert.addAction(defaultAction)
//Made Changes here
DispatchQueue.main.async(execute: {
self.present(alert, animated: true)
})

在这个线程中,我有一个自定义导航栏,我通过它调用了一个 AlertViewController。

我必须把它作为一个子元素添加到我的主视图控制器中。然后我就可以毫无征兆地称之为礼物了。

您应该将 Zoomed Image View Controller添加为主 ViewController 的子级。

(例如)

[self addChildViewController:ZoomedImageViewController];

然后您就可以调用 ZoomedImageViewController

[self presentViewController:ZoomedImageViewController];

许多答案都是正确的。

  • 检查你的 PresingViewController 有没有父视图控制器。
  • 如果没有,把它添加到应该添加的地方
  • 否则,递归地检查它的 ParentViewController 是否有 ParentViewController,直到每个 viewController 都有其父节点为止

当我的同事向 BViewController 添加一个 AViewController 时,这个问题发生在我身上。不知何故,他只是将 AViewController 的视图添加到 BViewController 的视图中。

通过添加 bViewController.addChild (aViewController)修复